@omnicross/daemon 0.2.1 → 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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 Sayo
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sayo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,19 +1,19 @@
1
- # @omnicross/daemon
2
-
3
- The omnicross standalone daemon — a bare-Node embedder of `@omnicross/core` with an admin HTTP API + dashboard. Ships the `omnicross` CLI for managing keys, providers, subscription OAuth login, and launching Code CLIs against an in-process proxy.
4
-
5
- Part of the [omnicross](https://github.com/Dumoedss/omnicross) monorepo — see the root README for the full overview.
6
-
7
- ```bash
8
- npm install -g @omnicross/daemon
9
- omnicross --help
10
- ```
11
-
12
- ```bash
13
- # Boot the daemon (BYO-key serving)
14
- omnicross start --config ./omnicross.config.json
15
- ```
16
-
17
- ## License
18
-
19
- [MIT](LICENSE)
1
+ # @omnicross/daemon
2
+
3
+ The omnicross standalone daemon — a bare-Node embedder of `@omnicross/core` with an admin HTTP API + dashboard. Ships the `omnicross` CLI for managing keys, providers, subscription OAuth login, and launching Code CLIs against an in-process proxy.
4
+
5
+ Part of the [omnicross](https://github.com/Dumoedss/omnicross) monorepo — see the root README for the full overview.
6
+
7
+ ```bash
8
+ npm install -g @omnicross/daemon
9
+ omnicross --help
10
+ ```
11
+
12
+ ```bash
13
+ # Boot the daemon (BYO-key serving)
14
+ omnicross start --config ./omnicross.config.json
15
+ ```
16
+
17
+ ## License
18
+
19
+ [MIT](LICENSE)
package/dist/cli.cjs CHANGED
@@ -1163,7 +1163,7 @@ var import_node_util2 = require("util");
1163
1163
  var import_outbound_api12 = require("@omnicross/core/outbound-api");
1164
1164
  var import_api4 = require("@omnicross/core/search/api");
1165
1165
  var import_http4 = require("@omnicross/core/search/http");
1166
- var import_search2 = require("@omnicross/core/search");
1166
+ var import_search3 = require("@omnicross/core/search");
1167
1167
 
1168
1168
  // src/bootstrap.ts
1169
1169
  var import_node_fs35 = require("fs");
@@ -1178,7 +1178,7 @@ var import_subscriptionRegistryPort = require("@omnicross/core/outbound-api/subs
1178
1178
  var import_SubscriptionAccountHealth4 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
1179
1179
  var import_AccountAllowanceStore4 = require("@omnicross/core/pipeline/AccountAllowanceStore");
1180
1180
  var import_AccountAllowanceScheduling5 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
1181
- var import_upstreamFetch8 = require("@omnicross/core/pipeline/upstreamFetch");
1181
+ var import_upstreamFetch9 = require("@omnicross/core/pipeline/upstreamFetch");
1182
1182
  var import_SubscriptionIdentityStore3 = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
1183
1183
  var import_gemini_code_assist_resolver = require("@omnicross/core/ports/gemini-code-assist-resolver");
1184
1184
  var import_provider_proxy4 = require("@omnicross/core/provider-proxy");
@@ -1984,7 +1984,7 @@ var import_outbound_api5 = require("@omnicross/core/outbound-api");
1984
1984
  var import_image_generation_types = require("@omnicross/contracts/image-generation-types");
1985
1985
  var import_AccountAllowanceScheduling2 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
1986
1986
  var import_SubscriptionAccountHealth = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
1987
- var import_upstreamFetch3 = require("@omnicross/core/pipeline/upstreamFetch");
1987
+ var import_upstreamFetch4 = require("@omnicross/core/pipeline/upstreamFetch");
1988
1988
 
1989
1989
  // src/image-generation/imagesConfigValidation.ts
1990
1990
  var import_outbound_api = require("@omnicross/core/outbound-api");
@@ -4509,6 +4509,7 @@ async function handleDashboard(deps) {
4509
4509
  var import_outbound_api2 = require("@omnicross/core/outbound-api");
4510
4510
  var import_api3 = require("@omnicross/core/search/api");
4511
4511
  var import_http3 = require("@omnicross/core/search/http");
4512
+ var import_search2 = require("@omnicross/core/search");
4512
4513
 
4513
4514
  // src/search/searchDoctorProjection.ts
4514
4515
  var import_search_types = require("@omnicross/contracts/search-types");
@@ -4569,7 +4570,7 @@ function buildSearchDoctorSnapshot(contributions = (0, import_http.builtinHttpSe
4569
4570
  }
4570
4571
  return rows;
4571
4572
  }
4572
- var SEARCH_DOCTOR_QUERY = "mozilla developer network http headers";
4573
+ var SEARCH_DOCTOR_QUERY = "MDN HTTP headers documentation";
4573
4574
  function classifyLiveSearchOutcome(providerId, outcome, checkedAt) {
4574
4575
  if (outcome.kind === "results") {
4575
4576
  if (outcome.count > 0) return { providerId, status: "healthy", checkedAt };
@@ -4628,6 +4629,7 @@ async function runSearchLiveChecks(contributions, now = () => (/* @__PURE__ */ n
4628
4629
  }
4629
4630
 
4630
4631
  // src/search/SearchAssembly.ts
4632
+ var import_upstreamFetch3 = require("@omnicross/core/pipeline/upstreamFetch");
4631
4633
  var import_search = require("@omnicross/core/search");
4632
4634
  var import_api2 = require("@omnicross/core/search/api");
4633
4635
  var import_http2 = require("@omnicross/core/search/http");
@@ -4644,11 +4646,24 @@ function searchPolicyFrom(config) {
4644
4646
  ...maxAttempts !== void 0 ? { maxAttempts } : {}
4645
4647
  };
4646
4648
  }
4649
+ function resolveSearchUpstreamDispatcher(url) {
4650
+ return (0, import_upstreamFetch3.resolveUpstreamDispatcher)({ url });
4651
+ }
4652
+ var searchUpstreamProxyConfig = createUpstreamProxyResolver();
4653
+ function resolveSearchUpstreamProxyConfig(url) {
4654
+ return searchUpstreamProxyConfig({ url });
4655
+ }
4647
4656
  function searchContributionsFrom(config) {
4648
4657
  return [
4649
- ...(0, import_http2.builtinHttpSearchContributions)(),
4658
+ ...(0, import_http2.builtinHttpSearchContributions)(
4659
+ (0, import_http2.createSearchHttpTransport)({
4660
+ resolveProxyDispatcher: resolveSearchUpstreamDispatcher,
4661
+ resolveProxyConfig: resolveSearchUpstreamProxyConfig
4662
+ })
4663
+ ),
4650
4664
  ...(0, import_api2.apiSearchContributions)(config.providers, {
4651
- egressPolicy: searchEgressPolicyFrom(config)
4665
+ egressPolicy: searchEgressPolicyFrom(config),
4666
+ resolveProxyDispatcher: resolveSearchUpstreamDispatcher
4652
4667
  })
4653
4668
  ];
4654
4669
  }
@@ -4792,6 +4807,18 @@ async function handleSearchDiagnostics(res, deps) {
4792
4807
  };
4793
4808
  return writeJson(res, 200, { diagnostics: snapshot });
4794
4809
  }
4810
+ function persistedSearchContributions(search, fetchImpl) {
4811
+ if (fetchImpl) {
4812
+ const egressPolicy = searchEgressPolicyFrom(search);
4813
+ return [
4814
+ ...(0, import_http3.builtinHttpSearchContributions)(
4815
+ (0, import_http3.createSearchHttpTransport)({ fetch: fetchImpl, egressPolicy })
4816
+ ),
4817
+ ...(0, import_api3.apiSearchContributions)(search.providers, { egressPolicy, fetchImpl })
4818
+ ];
4819
+ }
4820
+ return searchContributionsFrom(search);
4821
+ }
4795
4822
  async function handleSearchTest(req, res, deps) {
4796
4823
  const status = deps.searchStatus;
4797
4824
  const body = await readBodyOrReject(req, res);
@@ -4809,16 +4836,8 @@ async function handleSearchTest(req, res, deps) {
4809
4836
  if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && providers[providerId] === void 0) {
4810
4837
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4811
4838
  }
4812
- const egressPolicy = searchEgressPolicyFrom(search);
4813
4839
  const fetchImpl = status.testFetch;
4814
- const transport = fetchImpl ? (0, import_http3.createSearchHttpTransport)({ fetch: fetchImpl, egressPolicy }) : void 0;
4815
- const contributions = [
4816
- ...(0, import_http3.builtinHttpSearchContributions)(transport),
4817
- ...(0, import_api3.apiSearchContributions)(search.providers, {
4818
- egressPolicy,
4819
- ...fetchImpl ? { fetchImpl } : {}
4820
- })
4821
- ];
4840
+ const contributions = persistedSearchContributions(search, fetchImpl);
4822
4841
  const contribution = contributions.find((c) => c.id === providerId);
4823
4842
  if (!contribution) {
4824
4843
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
@@ -4866,41 +4885,42 @@ async function handleSearchQuery(req, res, deps) {
4866
4885
  if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && providers[providerId] === void 0) {
4867
4886
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4868
4887
  }
4869
- const egressPolicy = searchEgressPolicyFrom(search);
4870
4888
  const fetchImpl = status.testFetch;
4871
- const transport = fetchImpl ? (0, import_http3.createSearchHttpTransport)({ fetch: fetchImpl, egressPolicy }) : void 0;
4872
- const contributions = [
4873
- ...(0, import_http3.builtinHttpSearchContributions)(transport),
4874
- ...(0, import_api3.apiSearchContributions)(search.providers, {
4875
- egressPolicy,
4876
- ...fetchImpl ? { fetchImpl } : {}
4877
- })
4878
- ];
4879
- const contribution = contributions.find((c) => c.id === providerId);
4880
- if (!contribution) {
4881
- return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4882
- }
4889
+ const runtime = (0, import_search2.createSearchRuntime)({
4890
+ contributions: persistedSearchContributions(search, fetchImpl),
4891
+ policy: {
4892
+ ...searchPolicyFrom(search),
4893
+ // The panel always walks: it answers "does a search WORK for this
4894
+ // operator", not "does this one provider behave" — that is `/test`'s
4895
+ // job. The persisted policy's allowlist still bounds the walk.
4896
+ fallbackEnabled: true,
4897
+ preferred: providerId
4898
+ }
4899
+ });
4883
4900
  const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
4884
4901
  try {
4885
- const results = await contribution.provider.search(query2, { maxResults: 5 });
4902
+ const orchestrated = await runtime.search({ query: query2, options: { maxResults: 5 } });
4903
+ const results = orchestrated.results;
4886
4904
  const sanitized = results.slice(0, SEARCH_QUERY_MAX_RESULTS).map((result) => ({
4887
4905
  title: sanitizeResultField(result.title, SEARCH_RESULT_FIELD_CAPS.title),
4888
4906
  url: sanitizeResultField(result.url, SEARCH_RESULT_FIELD_CAPS.url),
4889
4907
  content: sanitizeResultField(result.content, SEARCH_RESULT_FIELD_CAPS.content)
4890
4908
  }));
4891
- const diagnostic = sanitized.length === 0 ? { providerId: contribution.id, status: "healthy", checkedAt } : classifyLiveSearchOutcome(
4892
- contribution.id,
4909
+ const diagnostic = sanitized.length === 0 ? { providerId: orchestrated.providerId, status: "healthy", checkedAt } : classifyLiveSearchOutcome(
4910
+ orchestrated.providerId,
4893
4911
  { kind: "results", count: sanitized.length },
4894
4912
  checkedAt
4895
4913
  );
4896
4914
  const response = {
4897
4915
  diagnostic,
4916
+ providerUsed: orchestrated.providerId,
4917
+ fallbackCount: orchestrated.fallbackCount,
4898
4918
  resultCount: sanitized.length,
4899
4919
  results: sanitized
4900
4920
  };
4901
4921
  return writeJson(res, 200, { result: response });
4902
4922
  } catch (error) {
4903
- const diagnostic = classifyLiveSearchOutcome(contribution.id, { kind: "failure", error }, checkedAt);
4923
+ const diagnostic = classifyLiveSearchOutcome(providerId, { kind: "failure", error }, checkedAt);
4904
4924
  const response = { diagnostic };
4905
4925
  return writeJson(res, 200, { result: response });
4906
4926
  }
@@ -6534,7 +6554,7 @@ async function handleDiscoverModels(res, id, cfg) {
6534
6554
  try {
6535
6555
  const headers = { Accept: "application/json" };
6536
6556
  if (resolvedKey) headers["Authorization"] = `Bearer ${resolvedKey}`;
6537
- const response = await (0, import_upstreamFetch3.fetchUpstream)(url, { method: "GET", headers }, { providerId: "byo" });
6557
+ const response = await (0, import_upstreamFetch4.fetchUpstream)(url, { method: "GET", headers }, { providerId: "byo" });
6538
6558
  if (!response.ok) {
6539
6559
  const text = await response.text().catch(() => "");
6540
6560
  let message = text.slice(0, 300);
@@ -6593,7 +6613,7 @@ async function handleTestModel(req, res, id, cfg) {
6593
6613
  }
6594
6614
  const startedAt = Date.now();
6595
6615
  try {
6596
- const response = await (0, import_upstreamFetch3.fetchUpstream)(
6616
+ const response = await (0, import_upstreamFetch4.fetchUpstream)(
6597
6617
  url,
6598
6618
  { method: "POST", headers, body: JSON.stringify(payload) },
6599
6619
  { providerId: "byo" }
@@ -8096,7 +8116,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
8096
8116
  }
8097
8117
 
8098
8118
  // src/admin/version.ts
8099
- var DAEMON_VERSION = true ? "0.2.1" : "0.0.0-dev";
8119
+ var DAEMON_VERSION = true ? "0.3.0" : "0.0.0-dev";
8100
8120
 
8101
8121
  // src/admin/AdminServer.ts
8102
8122
  var LOOPBACK_ADDR = "127.0.0.1";
@@ -15069,7 +15089,7 @@ var import_node_fs27 = require("fs");
15069
15089
  var import_node_path27 = require("path");
15070
15090
  var import_SubscriptionAccountHealth2 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
15071
15091
  var import_AccountAllowanceScheduling3 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
15072
- var import_upstreamFetch4 = require("@omnicross/core/pipeline/upstreamFetch");
15092
+ var import_upstreamFetch5 = require("@omnicross/core/pipeline/upstreamFetch");
15073
15093
  var import_SubscriptionIdentityStore2 = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
15074
15094
  var import_subscriptions5 = require("@omnicross/subscriptions");
15075
15095
 
@@ -15217,7 +15237,7 @@ var JsonSubscriptionCredentialStore = class {
15217
15237
  * a plaintext token pair into `upstream-trace.jsonl`.
15218
15238
  */
15219
15239
  buildRefreshFetch(providerId, accountId) {
15220
- return this.fetchImpl ?? ((url, init) => (0, import_upstreamFetch4.fetchUpstream)(url, init, { providerId, accountId, redactBodies: true }));
15240
+ return this.fetchImpl ?? ((url, init) => (0, import_upstreamFetch5.fetchUpstream)(url, init, { providerId, accountId, redactBodies: true }));
15221
15241
  }
15222
15242
  /**
15223
15243
  * In-flight refresh coalescing. OAuth refresh tokens are
@@ -15775,7 +15795,7 @@ var JsonSubscriptionCredentialStore = class {
15775
15795
  };
15776
15796
 
15777
15797
  // src/AccountHealthProbeScheduler.ts
15778
- var import_upstreamFetch5 = require("@omnicross/core/pipeline/upstreamFetch");
15798
+ var import_upstreamFetch6 = require("@omnicross/core/pipeline/upstreamFetch");
15779
15799
 
15780
15800
  // src/probe/CodexGenerationProbe.ts
15781
15801
  var import_codexCliHeaders = require("@omnicross/core/provider-proxy/identity/codexCliHeaders");
@@ -15936,7 +15956,7 @@ var AccountHealthProbeScheduler = class {
15936
15956
  this.logger = logger;
15937
15957
  this.config = config;
15938
15958
  this.now = opts.now ?? Date.now;
15939
- this.fetchImpl = opts.fetchImpl ?? import_upstreamFetch5.fetchUpstream;
15959
+ this.fetchImpl = opts.fetchImpl ?? import_upstreamFetch6.fetchUpstream;
15940
15960
  this.sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
15941
15961
  this.planFor = opts.planFor ?? probePlanFor;
15942
15962
  }
@@ -17092,7 +17112,7 @@ var AuditWriter = class {
17092
17112
  var import_node_fs33 = require("fs");
17093
17113
  var import_node_crypto24 = require("crypto");
17094
17114
  var import_node_path34 = require("path");
17095
- var import_upstreamFetch6 = require("@omnicross/core/pipeline/upstreamFetch");
17115
+ var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
17096
17116
 
17097
17117
  // src/billing/billingFiles.ts
17098
17118
  var BILLING_FILE_RE = /^billing-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
@@ -17115,7 +17135,7 @@ var BillingPublisher = class {
17115
17135
  constructor(billingDir, logger, opts = {}) {
17116
17136
  this.billingDir = billingDir;
17117
17137
  this.logger = logger;
17118
- this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch6.fetchUpstream)(url, init));
17138
+ this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch7.fetchUpstream)(url, init));
17119
17139
  this.defer = opts.defer ?? ((fn) => setTimeout(fn, 0));
17120
17140
  this.timeoutMs = opts.timeoutMs ?? BILLING_POST_TIMEOUT_MS;
17121
17141
  this.now = opts.now ?? Date.now;
@@ -17524,7 +17544,7 @@ function createRouteLeaseSubscriptionPreflight(credentials) {
17524
17544
 
17525
17545
  // src/webhook/WebhookDispatcher.ts
17526
17546
  var import_node_crypto25 = require("crypto");
17527
- var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
17547
+ var import_upstreamFetch8 = require("@omnicross/core/pipeline/upstreamFetch");
17528
17548
  var WEBHOOK_MAX_ATTEMPTS = 3;
17529
17549
  var WEBHOOK_QUEUE_MAX = 1e3;
17530
17550
  var WEBHOOK_SEND_TIMEOUT_MS = 1e4;
@@ -17544,7 +17564,7 @@ var WebhookDispatcher = class {
17544
17564
  sleep;
17545
17565
  now;
17546
17566
  constructor(opts = {}) {
17547
- this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch7.fetchUpstream)(url, init));
17567
+ this.fetchImpl = opts.fetchImpl ?? ((url, init) => (0, import_upstreamFetch8.fetchUpstream)(url, init));
17548
17568
  this.logger = opts.logger;
17549
17569
  this.maxAttempts = opts.maxAttempts ?? WEBHOOK_MAX_ATTEMPTS;
17550
17570
  this.queueMax = opts.queueMax ?? WEBHOOK_QUEUE_MAX;
@@ -17806,7 +17826,7 @@ function buildDaemon(config, paths) {
17806
17826
  );
17807
17827
  (0, import_subscriptions6.setSubscriptionProviderRegistry)(subscriptionRegistry);
17808
17828
  setServerProxyConfig(decryptedConfig.server?.proxy);
17809
- (0, import_upstreamFetch8.setUpstreamProxyResolver)(
17829
+ (0, import_upstreamFetch9.setUpstreamProxyResolver)(
17810
17830
  createUpstreamProxyResolver({
17811
17831
  getAccountProxy: (providerId, accountId) => credentialStore.getAccountProxy(providerId, accountId)
17812
17832
  })
@@ -17829,7 +17849,7 @@ function buildDaemon(config, paths) {
17829
17849
  const pricingEngine = new import_usage2.PricingEngine(pricingStore, logger, {
17830
17850
  // Catalog egress follows the same global/env proxy policy as every other
17831
17851
  // daemon upstream call; no provider/account override applies here.
17832
- fetchImpl: ((input, init) => (0, import_upstreamFetch8.fetchUpstream)(String(input), init ?? {}))
17852
+ fetchImpl: ((input, init) => (0, import_upstreamFetch9.fetchUpstream)(String(input), init ?? {}))
17833
17853
  });
17834
17854
  const pricingRefreshScheduler = new PricingRefreshScheduler(
17835
17855
  pricingEngine,
@@ -18109,7 +18129,7 @@ function buildDaemon(config, paths) {
18109
18129
  // — `server.proxy.byProvider[...]` was silently skipped — and the call was
18110
18130
  // excluded from the upstream trace, so a failing login left no evidence.
18111
18131
  // `redactBodies` keeps the code/verifier + minted token out of that trace.
18112
- oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => (0, import_upstreamFetch8.fetchUpstream)(url, init, { providerId, redactBodies: true }),
18132
+ oauthExchangeFetch: paths.oauthExchangeFetch ? () => paths.oauthExchangeFetch : (providerId) => (url, init) => (0, import_upstreamFetch9.fetchUpstream)(url, init, { providerId, redactBodies: true }),
18113
18133
  subscriptionAccountAppender: credentialStore,
18114
18134
  // Codex interactive OAuth (app-parity-2 child 5) — the async loopback flow store
18115
18135
  // + the one-shot 127.0.0.1:1455 listener. Token captured + persisted daemon-side;
@@ -18175,7 +18195,7 @@ function buildDaemon(config, paths) {
18175
18195
  });
18176
18196
  const webhookDispatcher = new WebhookDispatcher({
18177
18197
  logger,
18178
- fetchImpl: (url, init) => (0, import_upstreamFetch8.fetchUpstream)(url, init)
18198
+ fetchImpl: (url, init) => (0, import_upstreamFetch9.fetchUpstream)(url, init)
18179
18199
  });
18180
18200
  setWebhookRuntime(webhookDispatcher, (0, import_SubscriptionAccountHealth4.getSharedAccountHealth)());
18181
18201
  const auditWriter = new AuditWriter(auditDir, logger);
@@ -18448,9 +18468,9 @@ async function runSearchDoctor(live, env = process.env, source = {}) {
18448
18468
  ];
18449
18469
  const declarations = source.runtime?.listProviders() ?? contributions;
18450
18470
  console.info("omnicross doctor search \u2014 builtin search contributions (offline, no network)");
18451
- const modes = source.config?.modes ?? import_search2.DEFAULT_SEARCH_FRONTEND_MODES;
18471
+ const modes = source.config?.modes ?? import_search3.DEFAULT_SEARCH_FRONTEND_MODES;
18452
18472
  console.info(
18453
- ` [i] frontend modes: ${import_search2.SEARCH_FRONTEND_NAMES.map((name) => `${name}=${modes[name]}`).join(", ")}`
18473
+ ` [i] frontend modes: ${import_search3.SEARCH_FRONTEND_NAMES.map((name) => `${name}=${modes[name]}`).join(", ")}`
18454
18474
  );
18455
18475
  console.info(
18456
18476
  " [i] codex mode applies immediately; responses/anthropic modes, provider config, egress allowlist and policy apply on daemon restart"
@@ -19040,7 +19060,7 @@ function spawnCliInherit(plan) {
19040
19060
  var import_node_child_process3 = require("child_process");
19041
19061
  var import_node_readline2 = require("readline");
19042
19062
  var import_node_util7 = require("util");
19043
- var import_upstreamFetch9 = require("@omnicross/core/pipeline/upstreamFetch");
19063
+ var import_upstreamFetch10 = require("@omnicross/core/pipeline/upstreamFetch");
19044
19064
  var import_subscriptions7 = require("@omnicross/subscriptions");
19045
19065
  var PROVIDERS2 = ["claude", "codex", "gemini"];
19046
19066
  async function runLogin(argv, deps) {
@@ -19072,10 +19092,10 @@ async function runLogin(argv, deps) {
19072
19092
  };
19073
19093
  const box = resolveSecretBox(values["master-key-file"]);
19074
19094
  setSecretBox(box);
19075
- (0, import_upstreamFetch9.setUpstreamProxyResolver)(createUpstreamProxyResolver());
19095
+ (0, import_upstreamFetch10.setUpstreamProxyResolver)(createUpstreamProxyResolver());
19076
19096
  try {
19077
19097
  const tokensPath = defaultTokensPath(values.config);
19078
- const exchangeFetch = resolved.tokensFetch ?? ((url, init) => (0, import_upstreamFetch9.fetchUpstream)(url, init, { providerId: provider, redactBodies: true }));
19098
+ const exchangeFetch = resolved.tokensFetch ?? ((url, init) => (0, import_upstreamFetch10.fetchUpstream)(url, init, { providerId: provider, redactBodies: true }));
19079
19099
  const store = new JsonSubscriptionCredentialStore(tokensPath, box, exchangeFetch);
19080
19100
  const expiresAt = await runProviderLogin(
19081
19101
  provider,
@@ -19088,7 +19108,7 @@ async function runLogin(argv, deps) {
19088
19108
  console.info(` token: [stored, encrypted] expiresAt: ${expiresAt ?? "n/a"}`);
19089
19109
  } finally {
19090
19110
  setSecretBox(null);
19091
- (0, import_upstreamFetch9.setUpstreamProxyResolver)(null);
19111
+ (0, import_upstreamFetch10.setUpstreamProxyResolver)(null);
19092
19112
  }
19093
19113
  }
19094
19114
  async function runProviderLogin(provider, store, deps, exchangeFetch, label) {
package/dist/cli.js CHANGED
@@ -4599,7 +4599,8 @@ async function handleDashboard(deps) {
4599
4599
  // src/admin/searchAdminApi.ts
4600
4600
  import { DEFAULT_SEARCH_SERVER_CONFIG, loadServerConfig } from "@omnicross/core/outbound-api";
4601
4601
  import { apiSearchContributions as apiSearchContributions2 } from "@omnicross/core/search/api";
4602
- import { builtinHttpSearchContributions as builtinHttpSearchContributions3, createSearchHttpTransport } from "@omnicross/core/search/http";
4602
+ import { builtinHttpSearchContributions as builtinHttpSearchContributions3, createSearchHttpTransport as createSearchHttpTransport2 } from "@omnicross/core/search/http";
4603
+ import { createSearchRuntime as createSearchRuntime2 } from "@omnicross/core/search";
4603
4604
 
4604
4605
  // src/search/searchDoctorProjection.ts
4605
4606
  import { toSearchErrorShape } from "@omnicross/contracts/search-types";
@@ -4665,7 +4666,7 @@ function buildSearchDoctorSnapshot(contributions = builtinHttpSearchContribution
4665
4666
  }
4666
4667
  return rows;
4667
4668
  }
4668
- var SEARCH_DOCTOR_QUERY = "mozilla developer network http headers";
4669
+ var SEARCH_DOCTOR_QUERY = "MDN HTTP headers documentation";
4669
4670
  function classifyLiveSearchOutcome(providerId, outcome, checkedAt) {
4670
4671
  if (outcome.kind === "results") {
4671
4672
  if (outcome.count > 0) return { providerId, status: "healthy", checkedAt };
@@ -4724,9 +4725,13 @@ async function runSearchLiveChecks(contributions, now = () => (/* @__PURE__ */ n
4724
4725
  }
4725
4726
 
4726
4727
  // src/search/SearchAssembly.ts
4728
+ import { resolveUpstreamDispatcher } from "@omnicross/core/pipeline/upstreamFetch";
4727
4729
  import { createSearchRuntime } from "@omnicross/core/search";
4728
4730
  import { apiSearchContributions } from "@omnicross/core/search/api";
4729
- import { builtinHttpSearchContributions as builtinHttpSearchContributions2 } from "@omnicross/core/search/http";
4731
+ import {
4732
+ builtinHttpSearchContributions as builtinHttpSearchContributions2,
4733
+ createSearchHttpTransport
4734
+ } from "@omnicross/core/search/http";
4730
4735
  function searchEgressPolicyFrom(config) {
4731
4736
  const hosts = config.egress.allowedPrivateHosts;
4732
4737
  return hosts.length > 0 ? { allowedPrivateHosts: [...hosts] } : {};
@@ -4740,11 +4745,24 @@ function searchPolicyFrom(config) {
4740
4745
  ...maxAttempts !== void 0 ? { maxAttempts } : {}
4741
4746
  };
4742
4747
  }
4748
+ function resolveSearchUpstreamDispatcher(url) {
4749
+ return resolveUpstreamDispatcher({ url });
4750
+ }
4751
+ var searchUpstreamProxyConfig = createUpstreamProxyResolver();
4752
+ function resolveSearchUpstreamProxyConfig(url) {
4753
+ return searchUpstreamProxyConfig({ url });
4754
+ }
4743
4755
  function searchContributionsFrom(config) {
4744
4756
  return [
4745
- ...builtinHttpSearchContributions2(),
4757
+ ...builtinHttpSearchContributions2(
4758
+ createSearchHttpTransport({
4759
+ resolveProxyDispatcher: resolveSearchUpstreamDispatcher,
4760
+ resolveProxyConfig: resolveSearchUpstreamProxyConfig
4761
+ })
4762
+ ),
4746
4763
  ...apiSearchContributions(config.providers, {
4747
- egressPolicy: searchEgressPolicyFrom(config)
4764
+ egressPolicy: searchEgressPolicyFrom(config),
4765
+ resolveProxyDispatcher: resolveSearchUpstreamDispatcher
4748
4766
  })
4749
4767
  ];
4750
4768
  }
@@ -4888,6 +4906,18 @@ async function handleSearchDiagnostics(res, deps) {
4888
4906
  };
4889
4907
  return writeJson(res, 200, { diagnostics: snapshot });
4890
4908
  }
4909
+ function persistedSearchContributions(search, fetchImpl) {
4910
+ if (fetchImpl) {
4911
+ const egressPolicy = searchEgressPolicyFrom(search);
4912
+ return [
4913
+ ...builtinHttpSearchContributions3(
4914
+ createSearchHttpTransport2({ fetch: fetchImpl, egressPolicy })
4915
+ ),
4916
+ ...apiSearchContributions2(search.providers, { egressPolicy, fetchImpl })
4917
+ ];
4918
+ }
4919
+ return searchContributionsFrom(search);
4920
+ }
4891
4921
  async function handleSearchTest(req, res, deps) {
4892
4922
  const status = deps.searchStatus;
4893
4923
  const body = await readBodyOrReject(req, res);
@@ -4905,16 +4935,8 @@ async function handleSearchTest(req, res, deps) {
4905
4935
  if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && providers[providerId] === void 0) {
4906
4936
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4907
4937
  }
4908
- const egressPolicy = searchEgressPolicyFrom(search);
4909
4938
  const fetchImpl = status.testFetch;
4910
- const transport = fetchImpl ? createSearchHttpTransport({ fetch: fetchImpl, egressPolicy }) : void 0;
4911
- const contributions = [
4912
- ...builtinHttpSearchContributions3(transport),
4913
- ...apiSearchContributions2(search.providers, {
4914
- egressPolicy,
4915
- ...fetchImpl ? { fetchImpl } : {}
4916
- })
4917
- ];
4939
+ const contributions = persistedSearchContributions(search, fetchImpl);
4918
4940
  const contribution = contributions.find((c) => c.id === providerId);
4919
4941
  if (!contribution) {
4920
4942
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
@@ -4962,41 +4984,42 @@ async function handleSearchQuery(req, res, deps) {
4962
4984
  if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && providers[providerId] === void 0) {
4963
4985
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4964
4986
  }
4965
- const egressPolicy = searchEgressPolicyFrom(search);
4966
4987
  const fetchImpl = status.testFetch;
4967
- const transport = fetchImpl ? createSearchHttpTransport({ fetch: fetchImpl, egressPolicy }) : void 0;
4968
- const contributions = [
4969
- ...builtinHttpSearchContributions3(transport),
4970
- ...apiSearchContributions2(search.providers, {
4971
- egressPolicy,
4972
- ...fetchImpl ? { fetchImpl } : {}
4973
- })
4974
- ];
4975
- const contribution = contributions.find((c) => c.id === providerId);
4976
- if (!contribution) {
4977
- return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4978
- }
4988
+ const runtime = createSearchRuntime2({
4989
+ contributions: persistedSearchContributions(search, fetchImpl),
4990
+ policy: {
4991
+ ...searchPolicyFrom(search),
4992
+ // The panel always walks: it answers "does a search WORK for this
4993
+ // operator", not "does this one provider behave" — that is `/test`'s
4994
+ // job. The persisted policy's allowlist still bounds the walk.
4995
+ fallbackEnabled: true,
4996
+ preferred: providerId
4997
+ }
4998
+ });
4979
4999
  const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
4980
5000
  try {
4981
- const results = await contribution.provider.search(query2, { maxResults: 5 });
5001
+ const orchestrated = await runtime.search({ query: query2, options: { maxResults: 5 } });
5002
+ const results = orchestrated.results;
4982
5003
  const sanitized = results.slice(0, SEARCH_QUERY_MAX_RESULTS).map((result) => ({
4983
5004
  title: sanitizeResultField(result.title, SEARCH_RESULT_FIELD_CAPS.title),
4984
5005
  url: sanitizeResultField(result.url, SEARCH_RESULT_FIELD_CAPS.url),
4985
5006
  content: sanitizeResultField(result.content, SEARCH_RESULT_FIELD_CAPS.content)
4986
5007
  }));
4987
- const diagnostic = sanitized.length === 0 ? { providerId: contribution.id, status: "healthy", checkedAt } : classifyLiveSearchOutcome(
4988
- contribution.id,
5008
+ const diagnostic = sanitized.length === 0 ? { providerId: orchestrated.providerId, status: "healthy", checkedAt } : classifyLiveSearchOutcome(
5009
+ orchestrated.providerId,
4989
5010
  { kind: "results", count: sanitized.length },
4990
5011
  checkedAt
4991
5012
  );
4992
5013
  const response = {
4993
5014
  diagnostic,
5015
+ providerUsed: orchestrated.providerId,
5016
+ fallbackCount: orchestrated.fallbackCount,
4994
5017
  resultCount: sanitized.length,
4995
5018
  results: sanitized
4996
5019
  };
4997
5020
  return writeJson(res, 200, { result: response });
4998
5021
  } catch (error) {
4999
- const diagnostic = classifyLiveSearchOutcome(contribution.id, { kind: "failure", error }, checkedAt);
5022
+ const diagnostic = classifyLiveSearchOutcome(providerId, { kind: "failure", error }, checkedAt);
5000
5023
  const response = { diagnostic };
5001
5024
  return writeJson(res, 200, { result: response });
5002
5025
  }
@@ -8206,7 +8229,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
8206
8229
  }
8207
8230
 
8208
8231
  // src/admin/version.ts
8209
- var DAEMON_VERSION = true ? "0.2.1" : "0.0.0-dev";
8232
+ var DAEMON_VERSION = true ? "0.3.0" : "0.0.0-dev";
8210
8233
 
8211
8234
  // src/admin/AdminServer.ts
8212
8235
  var LOOPBACK_ADDR = "127.0.0.1";
package/dist/index.cjs CHANGED
@@ -70,7 +70,7 @@ var import_subscriptionRegistryPort = require("@omnicross/core/outbound-api/subs
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");
@@ -883,7 +883,7 @@ 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");
@@ -3743,6 +3743,7 @@ async function handleDashboard(deps) {
3743
3743
  var import_outbound_api2 = require("@omnicross/core/outbound-api");
3744
3744
  var import_api3 = require("@omnicross/core/search/api");
3745
3745
  var import_http3 = require("@omnicross/core/search/http");
3746
+ var import_search2 = require("@omnicross/core/search");
3746
3747
 
3747
3748
  // src/search/searchDoctorProjection.ts
3748
3749
  var import_search_types = require("@omnicross/contracts/search-types");
@@ -3803,7 +3804,7 @@ function buildSearchDoctorSnapshot(contributions = (0, import_http.builtinHttpSe
3803
3804
  }
3804
3805
  return rows;
3805
3806
  }
3806
- var SEARCH_DOCTOR_QUERY = "mozilla developer network http headers";
3807
+ var SEARCH_DOCTOR_QUERY = "MDN HTTP headers documentation";
3807
3808
  function classifyLiveSearchOutcome(providerId, outcome, checkedAt) {
3808
3809
  if (outcome.kind === "results") {
3809
3810
  if (outcome.count > 0) return { providerId, status: "healthy", checkedAt };
@@ -3848,6 +3849,7 @@ function classifySearchFailure(stage, code) {
3848
3849
  }
3849
3850
 
3850
3851
  // src/search/SearchAssembly.ts
3852
+ var import_upstreamFetch3 = require("@omnicross/core/pipeline/upstreamFetch");
3851
3853
  var import_search = require("@omnicross/core/search");
3852
3854
  var import_api2 = require("@omnicross/core/search/api");
3853
3855
  var import_http2 = require("@omnicross/core/search/http");
@@ -3864,11 +3866,24 @@ function searchPolicyFrom(config) {
3864
3866
  ...maxAttempts !== void 0 ? { maxAttempts } : {}
3865
3867
  };
3866
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
+ }
3867
3876
  function searchContributionsFrom(config) {
3868
3877
  return [
3869
- ...(0, import_http2.builtinHttpSearchContributions)(),
3878
+ ...(0, import_http2.builtinHttpSearchContributions)(
3879
+ (0, import_http2.createSearchHttpTransport)({
3880
+ resolveProxyDispatcher: resolveSearchUpstreamDispatcher,
3881
+ resolveProxyConfig: resolveSearchUpstreamProxyConfig
3882
+ })
3883
+ ),
3870
3884
  ...(0, import_api2.apiSearchContributions)(config.providers, {
3871
- egressPolicy: searchEgressPolicyFrom(config)
3885
+ egressPolicy: searchEgressPolicyFrom(config),
3886
+ resolveProxyDispatcher: resolveSearchUpstreamDispatcher
3872
3887
  })
3873
3888
  ];
3874
3889
  }
@@ -4012,6 +4027,18 @@ async function handleSearchDiagnostics(res, deps) {
4012
4027
  };
4013
4028
  return writeJson(res, 200, { diagnostics: snapshot });
4014
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
+ }
4015
4042
  async function handleSearchTest(req, res, deps) {
4016
4043
  const status = deps.searchStatus;
4017
4044
  const body = await readBodyOrReject(req, res);
@@ -4029,16 +4056,8 @@ async function handleSearchTest(req, res, deps) {
4029
4056
  if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && providers[providerId] === void 0) {
4030
4057
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4031
4058
  }
4032
- const egressPolicy = searchEgressPolicyFrom(search);
4033
4059
  const fetchImpl = status.testFetch;
4034
- const transport = fetchImpl ? (0, import_http3.createSearchHttpTransport)({ fetch: fetchImpl, egressPolicy }) : void 0;
4035
- const contributions = [
4036
- ...(0, import_http3.builtinHttpSearchContributions)(transport),
4037
- ...(0, import_api3.apiSearchContributions)(search.providers, {
4038
- egressPolicy,
4039
- ...fetchImpl ? { fetchImpl } : {}
4040
- })
4041
- ];
4060
+ const contributions = persistedSearchContributions(search, fetchImpl);
4042
4061
  const contribution = contributions.find((c) => c.id === providerId);
4043
4062
  if (!contribution) {
4044
4063
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
@@ -4086,41 +4105,42 @@ async function handleSearchQuery(req, res, deps) {
4086
4105
  if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && providers[providerId] === void 0) {
4087
4106
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4088
4107
  }
4089
- const egressPolicy = searchEgressPolicyFrom(search);
4090
4108
  const fetchImpl = status.testFetch;
4091
- const transport = fetchImpl ? (0, import_http3.createSearchHttpTransport)({ fetch: fetchImpl, egressPolicy }) : void 0;
4092
- const contributions = [
4093
- ...(0, import_http3.builtinHttpSearchContributions)(transport),
4094
- ...(0, import_api3.apiSearchContributions)(search.providers, {
4095
- egressPolicy,
4096
- ...fetchImpl ? { fetchImpl } : {}
4097
- })
4098
- ];
4099
- const contribution = contributions.find((c) => c.id === providerId);
4100
- if (!contribution) {
4101
- return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4102
- }
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
+ });
4103
4120
  const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
4104
4121
  try {
4105
- const results = await contribution.provider.search(query2, { maxResults: 5 });
4122
+ const orchestrated = await runtime.search({ query: query2, options: { maxResults: 5 } });
4123
+ const results = orchestrated.results;
4106
4124
  const sanitized = results.slice(0, SEARCH_QUERY_MAX_RESULTS).map((result) => ({
4107
4125
  title: sanitizeResultField(result.title, SEARCH_RESULT_FIELD_CAPS.title),
4108
4126
  url: sanitizeResultField(result.url, SEARCH_RESULT_FIELD_CAPS.url),
4109
4127
  content: sanitizeResultField(result.content, SEARCH_RESULT_FIELD_CAPS.content)
4110
4128
  }));
4111
- const diagnostic = sanitized.length === 0 ? { providerId: contribution.id, status: "healthy", checkedAt } : classifyLiveSearchOutcome(
4112
- contribution.id,
4129
+ const diagnostic = sanitized.length === 0 ? { providerId: orchestrated.providerId, status: "healthy", checkedAt } : classifyLiveSearchOutcome(
4130
+ orchestrated.providerId,
4113
4131
  { kind: "results", count: sanitized.length },
4114
4132
  checkedAt
4115
4133
  );
4116
4134
  const response = {
4117
4135
  diagnostic,
4136
+ providerUsed: orchestrated.providerId,
4137
+ fallbackCount: orchestrated.fallbackCount,
4118
4138
  resultCount: sanitized.length,
4119
4139
  results: sanitized
4120
4140
  };
4121
4141
  return writeJson(res, 200, { result: response });
4122
4142
  } catch (error) {
4123
- const diagnostic = classifyLiveSearchOutcome(contribution.id, { kind: "failure", error }, checkedAt);
4143
+ const diagnostic = classifyLiveSearchOutcome(providerId, { kind: "failure", error }, checkedAt);
4124
4144
  const response = { diagnostic };
4125
4145
  return writeJson(res, 200, { result: response });
4126
4146
  }
@@ -5770,7 +5790,7 @@ async function handleDiscoverModels(res, id, cfg) {
5770
5790
  try {
5771
5791
  const headers = { Accept: "application/json" };
5772
5792
  if (resolvedKey) headers["Authorization"] = `Bearer ${resolvedKey}`;
5773
- 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" });
5774
5794
  if (!response.ok) {
5775
5795
  const text = await response.text().catch(() => "");
5776
5796
  let message = text.slice(0, 300);
@@ -5829,7 +5849,7 @@ async function handleTestModel(req, res, id, cfg) {
5829
5849
  }
5830
5850
  const startedAt = Date.now();
5831
5851
  try {
5832
- const response = await (0, import_upstreamFetch3.fetchUpstream)(
5852
+ const response = await (0, import_upstreamFetch4.fetchUpstream)(
5833
5853
  url,
5834
5854
  { method: "POST", headers, body: JSON.stringify(payload) },
5835
5855
  { providerId: "byo" }
@@ -7332,7 +7352,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
7332
7352
  }
7333
7353
 
7334
7354
  // src/admin/version.ts
7335
- var DAEMON_VERSION = true ? "0.2.1" : "0.0.0-dev";
7355
+ var DAEMON_VERSION = true ? "0.3.0" : "0.0.0-dev";
7336
7356
 
7337
7357
  // src/admin/AdminServer.ts
7338
7358
  var LOOPBACK_ADDR = "127.0.0.1";
@@ -14338,7 +14358,7 @@ var import_node_fs23 = require("fs");
14338
14358
  var import_node_path24 = require("path");
14339
14359
  var import_SubscriptionAccountHealth2 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
14340
14360
  var import_AccountAllowanceScheduling3 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
14341
- var import_upstreamFetch4 = require("@omnicross/core/pipeline/upstreamFetch");
14361
+ var import_upstreamFetch5 = require("@omnicross/core/pipeline/upstreamFetch");
14342
14362
  var import_SubscriptionIdentityStore2 = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
14343
14363
  var import_subscriptions5 = require("@omnicross/subscriptions");
14344
14364
 
@@ -14486,7 +14506,7 @@ var JsonSubscriptionCredentialStore = class {
14486
14506
  * a plaintext token pair into `upstream-trace.jsonl`.
14487
14507
  */
14488
14508
  buildRefreshFetch(providerId, accountId) {
14489
- 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 }));
14490
14510
  }
14491
14511
  /**
14492
14512
  * In-flight refresh coalescing. OAuth refresh tokens are
@@ -15044,7 +15064,7 @@ var JsonSubscriptionCredentialStore = class {
15044
15064
  };
15045
15065
 
15046
15066
  // src/AccountHealthProbeScheduler.ts
15047
- var import_upstreamFetch5 = require("@omnicross/core/pipeline/upstreamFetch");
15067
+ var import_upstreamFetch6 = require("@omnicross/core/pipeline/upstreamFetch");
15048
15068
 
15049
15069
  // src/probe/CodexGenerationProbe.ts
15050
15070
  var import_codexCliHeaders = require("@omnicross/core/provider-proxy/identity/codexCliHeaders");
@@ -15205,7 +15225,7 @@ var AccountHealthProbeScheduler = class {
15205
15225
  this.logger = logger;
15206
15226
  this.config = config;
15207
15227
  this.now = opts.now ?? Date.now;
15208
- this.fetchImpl = opts.fetchImpl ?? import_upstreamFetch5.fetchUpstream;
15228
+ this.fetchImpl = opts.fetchImpl ?? import_upstreamFetch6.fetchUpstream;
15209
15229
  this.sleep = opts.sleep ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
15210
15230
  this.planFor = opts.planFor ?? probePlanFor;
15211
15231
  }
@@ -16903,7 +16923,7 @@ var AuditWriter = class {
16903
16923
  var import_node_fs32 = require("fs");
16904
16924
  var import_node_crypto24 = require("crypto");
16905
16925
  var import_node_path33 = require("path");
16906
- var import_upstreamFetch6 = require("@omnicross/core/pipeline/upstreamFetch");
16926
+ var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
16907
16927
 
16908
16928
  // src/billing/billingFiles.ts
16909
16929
  var BILLING_FILE_RE = /^billing-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
@@ -16926,7 +16946,7 @@ var BillingPublisher = class {
16926
16946
  constructor(billingDir, logger, opts = {}) {
16927
16947
  this.billingDir = billingDir;
16928
16948
  this.logger = logger;
16929
- 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));
16930
16950
  this.defer = opts.defer ?? ((fn) => setTimeout(fn, 0));
16931
16951
  this.timeoutMs = opts.timeoutMs ?? BILLING_POST_TIMEOUT_MS;
16932
16952
  this.now = opts.now ?? Date.now;
@@ -17335,7 +17355,7 @@ function createRouteLeaseSubscriptionPreflight(credentials) {
17335
17355
 
17336
17356
  // src/webhook/WebhookDispatcher.ts
17337
17357
  var import_node_crypto25 = require("crypto");
17338
- var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
17358
+ var import_upstreamFetch8 = require("@omnicross/core/pipeline/upstreamFetch");
17339
17359
  var WEBHOOK_MAX_ATTEMPTS = 3;
17340
17360
  var WEBHOOK_QUEUE_MAX = 1e3;
17341
17361
  var WEBHOOK_SEND_TIMEOUT_MS = 1e4;
@@ -17355,7 +17375,7 @@ var WebhookDispatcher = class {
17355
17375
  sleep;
17356
17376
  now;
17357
17377
  constructor(opts = {}) {
17358
- 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));
17359
17379
  this.logger = opts.logger;
17360
17380
  this.maxAttempts = opts.maxAttempts ?? WEBHOOK_MAX_ATTEMPTS;
17361
17381
  this.queueMax = opts.queueMax ?? WEBHOOK_QUEUE_MAX;
@@ -17622,7 +17642,7 @@ function buildDaemon(config, paths) {
17622
17642
  );
17623
17643
  (0, import_subscriptions6.setSubscriptionProviderRegistry)(subscriptionRegistry);
17624
17644
  setServerProxyConfig(decryptedConfig.server?.proxy);
17625
- (0, import_upstreamFetch8.setUpstreamProxyResolver)(
17645
+ (0, import_upstreamFetch9.setUpstreamProxyResolver)(
17626
17646
  createUpstreamProxyResolver({
17627
17647
  getAccountProxy: (providerId, accountId) => credentialStore.getAccountProxy(providerId, accountId)
17628
17648
  })
@@ -17645,7 +17665,7 @@ function buildDaemon(config, paths) {
17645
17665
  const pricingEngine = new import_usage2.PricingEngine(pricingStore, logger, {
17646
17666
  // Catalog egress follows the same global/env proxy policy as every other
17647
17667
  // daemon upstream call; no provider/account override applies here.
17648
- fetchImpl: ((input, init) => (0, import_upstreamFetch8.fetchUpstream)(String(input), init ?? {}))
17668
+ fetchImpl: ((input, init) => (0, import_upstreamFetch9.fetchUpstream)(String(input), init ?? {}))
17649
17669
  });
17650
17670
  const pricingRefreshScheduler = new PricingRefreshScheduler(
17651
17671
  pricingEngine,
@@ -17925,7 +17945,7 @@ function buildDaemon(config, paths) {
17925
17945
  // — `server.proxy.byProvider[...]` was silently skipped — and the call was
17926
17946
  // excluded from the upstream trace, so a failing login left no evidence.
17927
17947
  // `redactBodies` keeps the code/verifier + minted token out of that trace.
17928
- 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 }),
17929
17949
  subscriptionAccountAppender: credentialStore,
17930
17950
  // Codex interactive OAuth (app-parity-2 child 5) — the async loopback flow store
17931
17951
  // + the one-shot 127.0.0.1:1455 listener. Token captured + persisted daemon-side;
@@ -17991,7 +18011,7 @@ function buildDaemon(config, paths) {
17991
18011
  });
17992
18012
  const webhookDispatcher = new WebhookDispatcher({
17993
18013
  logger,
17994
- fetchImpl: (url, init) => (0, import_upstreamFetch8.fetchUpstream)(url, init)
18014
+ fetchImpl: (url, init) => (0, import_upstreamFetch9.fetchUpstream)(url, init)
17995
18015
  });
17996
18016
  setWebhookRuntime(webhookDispatcher, (0, import_SubscriptionAccountHealth4.getSharedAccountHealth)());
17997
18017
  const auditWriter = new AuditWriter(auditDir, logger);
@@ -18073,7 +18093,7 @@ function resetDaemonSingletonsForTests() {
18073
18093
  (0, import_subscriptionRegistryPort.setSubscriptionRegistryForOutbound)(null);
18074
18094
  (0, import_subscriptions6.setSubscriptionProviderRegistry)(null);
18075
18095
  (0, import_subscriptions6.setSubscriptionAccountService)(null);
18076
- (0, import_upstreamFetch8.setUpstreamProxyResolver)(null);
18096
+ (0, import_upstreamFetch9.setUpstreamProxyResolver)(null);
18077
18097
  setServerProxyConfig(void 0);
18078
18098
  (0, import_gemini_code_assist_resolver.setGeminiCodeAssistResolver)(null);
18079
18099
  setSecretBox(null);
package/dist/index.js CHANGED
@@ -3789,7 +3789,8 @@ async function handleDashboard(deps) {
3789
3789
  // src/admin/searchAdminApi.ts
3790
3790
  import { DEFAULT_SEARCH_SERVER_CONFIG, loadServerConfig } from "@omnicross/core/outbound-api";
3791
3791
  import { apiSearchContributions as apiSearchContributions2 } from "@omnicross/core/search/api";
3792
- import { builtinHttpSearchContributions as builtinHttpSearchContributions3, createSearchHttpTransport } from "@omnicross/core/search/http";
3792
+ import { builtinHttpSearchContributions as builtinHttpSearchContributions3, createSearchHttpTransport as createSearchHttpTransport2 } from "@omnicross/core/search/http";
3793
+ import { createSearchRuntime as createSearchRuntime2 } from "@omnicross/core/search";
3793
3794
 
3794
3795
  // src/search/searchDoctorProjection.ts
3795
3796
  import { toSearchErrorShape } from "@omnicross/contracts/search-types";
@@ -3855,7 +3856,7 @@ function buildSearchDoctorSnapshot(contributions = builtinHttpSearchContribution
3855
3856
  }
3856
3857
  return rows;
3857
3858
  }
3858
- var SEARCH_DOCTOR_QUERY = "mozilla developer network http headers";
3859
+ var SEARCH_DOCTOR_QUERY = "MDN HTTP headers documentation";
3859
3860
  function classifyLiveSearchOutcome(providerId, outcome, checkedAt) {
3860
3861
  if (outcome.kind === "results") {
3861
3862
  if (outcome.count > 0) return { providerId, status: "healthy", checkedAt };
@@ -3900,9 +3901,13 @@ function classifySearchFailure(stage, code) {
3900
3901
  }
3901
3902
 
3902
3903
  // src/search/SearchAssembly.ts
3904
+ import { resolveUpstreamDispatcher } from "@omnicross/core/pipeline/upstreamFetch";
3903
3905
  import { createSearchRuntime } from "@omnicross/core/search";
3904
3906
  import { apiSearchContributions } from "@omnicross/core/search/api";
3905
- import { builtinHttpSearchContributions as builtinHttpSearchContributions2 } from "@omnicross/core/search/http";
3907
+ import {
3908
+ builtinHttpSearchContributions as builtinHttpSearchContributions2,
3909
+ createSearchHttpTransport
3910
+ } from "@omnicross/core/search/http";
3906
3911
  function searchEgressPolicyFrom(config) {
3907
3912
  const hosts = config.egress.allowedPrivateHosts;
3908
3913
  return hosts.length > 0 ? { allowedPrivateHosts: [...hosts] } : {};
@@ -3916,11 +3921,24 @@ function searchPolicyFrom(config) {
3916
3921
  ...maxAttempts !== void 0 ? { maxAttempts } : {}
3917
3922
  };
3918
3923
  }
3924
+ function resolveSearchUpstreamDispatcher(url) {
3925
+ return resolveUpstreamDispatcher({ url });
3926
+ }
3927
+ var searchUpstreamProxyConfig = createUpstreamProxyResolver();
3928
+ function resolveSearchUpstreamProxyConfig(url) {
3929
+ return searchUpstreamProxyConfig({ url });
3930
+ }
3919
3931
  function searchContributionsFrom(config) {
3920
3932
  return [
3921
- ...builtinHttpSearchContributions2(),
3933
+ ...builtinHttpSearchContributions2(
3934
+ createSearchHttpTransport({
3935
+ resolveProxyDispatcher: resolveSearchUpstreamDispatcher,
3936
+ resolveProxyConfig: resolveSearchUpstreamProxyConfig
3937
+ })
3938
+ ),
3922
3939
  ...apiSearchContributions(config.providers, {
3923
- egressPolicy: searchEgressPolicyFrom(config)
3940
+ egressPolicy: searchEgressPolicyFrom(config),
3941
+ resolveProxyDispatcher: resolveSearchUpstreamDispatcher
3924
3942
  })
3925
3943
  ];
3926
3944
  }
@@ -4064,6 +4082,18 @@ async function handleSearchDiagnostics(res, deps) {
4064
4082
  };
4065
4083
  return writeJson(res, 200, { diagnostics: snapshot });
4066
4084
  }
4085
+ function persistedSearchContributions(search, fetchImpl) {
4086
+ if (fetchImpl) {
4087
+ const egressPolicy = searchEgressPolicyFrom(search);
4088
+ return [
4089
+ ...builtinHttpSearchContributions3(
4090
+ createSearchHttpTransport2({ fetch: fetchImpl, egressPolicy })
4091
+ ),
4092
+ ...apiSearchContributions2(search.providers, { egressPolicy, fetchImpl })
4093
+ ];
4094
+ }
4095
+ return searchContributionsFrom(search);
4096
+ }
4067
4097
  async function handleSearchTest(req, res, deps) {
4068
4098
  const status = deps.searchStatus;
4069
4099
  const body = await readBodyOrReject(req, res);
@@ -4081,16 +4111,8 @@ async function handleSearchTest(req, res, deps) {
4081
4111
  if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && providers[providerId] === void 0) {
4082
4112
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4083
4113
  }
4084
- const egressPolicy = searchEgressPolicyFrom(search);
4085
4114
  const fetchImpl = status.testFetch;
4086
- const transport = fetchImpl ? createSearchHttpTransport({ fetch: fetchImpl, egressPolicy }) : void 0;
4087
- const contributions = [
4088
- ...builtinHttpSearchContributions3(transport),
4089
- ...apiSearchContributions2(search.providers, {
4090
- egressPolicy,
4091
- ...fetchImpl ? { fetchImpl } : {}
4092
- })
4093
- ];
4115
+ const contributions = persistedSearchContributions(search, fetchImpl);
4094
4116
  const contribution = contributions.find((c) => c.id === providerId);
4095
4117
  if (!contribution) {
4096
4118
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
@@ -4138,41 +4160,42 @@ async function handleSearchQuery(req, res, deps) {
4138
4160
  if (!KEYLESS_HTTP_PROVIDER_IDS.has(providerId) && providers[providerId] === void 0) {
4139
4161
  return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4140
4162
  }
4141
- const egressPolicy = searchEgressPolicyFrom(search);
4142
4163
  const fetchImpl = status.testFetch;
4143
- const transport = fetchImpl ? createSearchHttpTransport({ fetch: fetchImpl, egressPolicy }) : void 0;
4144
- const contributions = [
4145
- ...builtinHttpSearchContributions3(transport),
4146
- ...apiSearchContributions2(search.providers, {
4147
- egressPolicy,
4148
- ...fetchImpl ? { fetchImpl } : {}
4149
- })
4150
- ];
4151
- const contribution = contributions.find((c) => c.id === providerId);
4152
- if (!contribution) {
4153
- return writeErr(res, 400, `search provider '${providerId}' is not configured`);
4154
- }
4164
+ const runtime = createSearchRuntime2({
4165
+ contributions: persistedSearchContributions(search, fetchImpl),
4166
+ policy: {
4167
+ ...searchPolicyFrom(search),
4168
+ // The panel always walks: it answers "does a search WORK for this
4169
+ // operator", not "does this one provider behave" — that is `/test`'s
4170
+ // job. The persisted policy's allowlist still bounds the walk.
4171
+ fallbackEnabled: true,
4172
+ preferred: providerId
4173
+ }
4174
+ });
4155
4175
  const checkedAt = (/* @__PURE__ */ new Date()).toISOString();
4156
4176
  try {
4157
- const results = await contribution.provider.search(query2, { maxResults: 5 });
4177
+ const orchestrated = await runtime.search({ query: query2, options: { maxResults: 5 } });
4178
+ const results = orchestrated.results;
4158
4179
  const sanitized = results.slice(0, SEARCH_QUERY_MAX_RESULTS).map((result) => ({
4159
4180
  title: sanitizeResultField(result.title, SEARCH_RESULT_FIELD_CAPS.title),
4160
4181
  url: sanitizeResultField(result.url, SEARCH_RESULT_FIELD_CAPS.url),
4161
4182
  content: sanitizeResultField(result.content, SEARCH_RESULT_FIELD_CAPS.content)
4162
4183
  }));
4163
- const diagnostic = sanitized.length === 0 ? { providerId: contribution.id, status: "healthy", checkedAt } : classifyLiveSearchOutcome(
4164
- contribution.id,
4184
+ const diagnostic = sanitized.length === 0 ? { providerId: orchestrated.providerId, status: "healthy", checkedAt } : classifyLiveSearchOutcome(
4185
+ orchestrated.providerId,
4165
4186
  { kind: "results", count: sanitized.length },
4166
4187
  checkedAt
4167
4188
  );
4168
4189
  const response = {
4169
4190
  diagnostic,
4191
+ providerUsed: orchestrated.providerId,
4192
+ fallbackCount: orchestrated.fallbackCount,
4170
4193
  resultCount: sanitized.length,
4171
4194
  results: sanitized
4172
4195
  };
4173
4196
  return writeJson(res, 200, { result: response });
4174
4197
  } catch (error) {
4175
- const diagnostic = classifyLiveSearchOutcome(contribution.id, { kind: "failure", error }, checkedAt);
4198
+ const diagnostic = classifyLiveSearchOutcome(providerId, { kind: "failure", error }, checkedAt);
4176
4199
  const response = { diagnostic };
4177
4200
  return writeJson(res, 200, { result: response });
4178
4201
  }
@@ -7398,7 +7421,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
7398
7421
  }
7399
7422
 
7400
7423
  // src/admin/version.ts
7401
- var DAEMON_VERSION = true ? "0.2.1" : "0.0.0-dev";
7424
+ var DAEMON_VERSION = true ? "0.3.0" : "0.0.0-dev";
7402
7425
 
7403
7426
  // src/admin/AdminServer.ts
7404
7427
  var LOOPBACK_ADDR = "127.0.0.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnicross/daemon",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Omnicross standalone daemon — the bare-Node embedder of @omnicross/core with an admin HTTP API + dashboard.",
5
5
  "license": "MIT",
6
6
  "author": "Sayo (https://github.com/Dumoedss)",
@@ -54,10 +54,10 @@
54
54
  "typecheck": "tsc -p tsconfig.typecheck.json --noEmit"
55
55
  },
56
56
  "dependencies": {
57
- "@omnicross/contracts": "^0.2.1",
58
- "@omnicross/core": "^0.2.1",
59
- "@omnicross/subscriptions": "^0.2.1",
60
- "@omnicross/cli-launcher": "^0.2.1",
61
- "@omnicross/ui": "^0.2.1"
57
+ "@omnicross/contracts": "^0.3.0",
58
+ "@omnicross/core": "^0.3.0",
59
+ "@omnicross/subscriptions": "^0.3.0",
60
+ "@omnicross/cli-launcher": "^0.3.0",
61
+ "@omnicross/ui": "^0.3.0"
62
62
  }
63
63
  }