@evomap/evolver 1.89.4 → 1.89.6
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/CONTRIBUTING.md +19 -0
- package/README.md +536 -86
- package/assets/cover.png +0 -0
- package/index.js +87 -7
- package/package.json +17 -6
- package/scripts/a2a_export.js +63 -0
- package/scripts/a2a_ingest.js +79 -0
- package/scripts/a2a_promote.js +118 -0
- package/scripts/analyze_by_skill.js +121 -0
- package/scripts/build_binaries.js +479 -0
- package/scripts/check-changelog.js +166 -0
- package/scripts/extract_log.js +85 -0
- package/scripts/generate_history.js +75 -0
- package/scripts/gep_append_event.js +96 -0
- package/scripts/gep_personality_report.js +234 -0
- package/scripts/human_report.js +147 -0
- package/scripts/recall-verify-report.js +234 -0
- package/scripts/recover_loop.js +61 -0
- package/scripts/refresh_stars_badge.js +168 -0
- package/scripts/seed-merchants.js +91 -0
- package/scripts/suggest_version.js +89 -0
- package/scripts/validate-modules.js +38 -0
- package/scripts/validate-suite.js +78 -0
- package/skills/index.json +14 -0
- package/src/adapters/scripts/_runtimePaths.js +1 -0
- package/src/adapters/scripts/evolver-session-end.js +1 -0
- package/src/adapters/scripts/evolver-session-start.js +1 -0
- package/src/evolve/guards.js +1 -721
- package/src/evolve/pipeline/collect.js +1 -1283
- package/src/evolve/pipeline/dispatch.js +1 -421
- package/src/evolve/pipeline/enrich.js +1 -440
- package/src/evolve/pipeline/hub.js +1 -319
- package/src/evolve/pipeline/select.js +1 -274
- package/src/evolve/pipeline/signals.js +1 -206
- package/src/evolve/utils.js +1 -264
- package/src/evolve.js +1 -350
- package/src/gep/a2aProtocol.js +1 -4455
- package/src/gep/antiAbuseTelemetry.js +1 -233
- package/src/gep/autoDistillConv.js +1 -205
- package/src/gep/autoDistillLlm.js +1 -315
- package/src/gep/candidateEval.js +1 -92
- package/src/gep/candidates.js +1 -198
- package/src/gep/contentHash.js +1 -30
- package/src/gep/conversationSniffer.js +1 -266
- package/src/gep/crypto.js +1 -89
- package/src/gep/curriculum.js +1 -163
- package/src/gep/deviceId.js +1 -218
- package/src/gep/envFingerprint.js +1 -118
- package/src/gep/epigenetics.js +1 -31
- package/src/gep/execBridge.js +1 -711
- package/src/gep/explore.js +1 -289
- package/src/gep/hash.js +1 -15
- package/src/gep/hubFetch.js +1 -359
- package/src/gep/hubReview.js +1 -207
- package/src/gep/hubSearch.js +1 -526
- package/src/gep/hubVerify.js +1 -306
- package/src/gep/idleScheduler.js +6 -1
- package/src/gep/learningSignals.js +1 -89
- package/src/gep/memoryGraph.js +1 -1374
- package/src/gep/memoryGraphAdapter.js +1 -203
- package/src/gep/mutation.js +1 -203
- package/src/gep/narrativeMemory.js +1 -108
- package/src/gep/openPRRegistry.js +1 -205
- package/src/gep/personality.js +1 -423
- package/src/gep/policyCheck.js +1 -599
- package/src/gep/prompt.js +1 -836
- package/src/gep/recallInject.js +1 -409
- package/src/gep/recallVerifier.js +1 -318
- package/src/gep/reflection.js +1 -177
- package/src/gep/savingsCore.js +1 -0
- package/src/gep/selector.js +1 -602
- package/src/gep/skillDistiller.js +1 -1294
- package/src/gep/solidify.js +1 -1699
- package/src/gep/strategy.js +1 -136
- package/src/gep/tokenSavings.js +1 -88
- package/src/gep/workspaceKeychain.js +1 -174
- package/src/ops/lifecycle.js +17 -4
- package/src/proxy/envelope.js +59 -0
- package/src/proxy/extensions/traceControl.js +1 -99
- package/src/proxy/index.js +221 -3
- package/src/proxy/inject.js +1 -52
- package/src/proxy/lifecycle/manager.js +14 -7
- package/src/proxy/mailbox/store.js +29 -6
- package/src/proxy/router/messages_route.js +4 -1
- package/src/proxy/router/responses_route.js +159 -0
- package/src/proxy/server/http.js +13 -4
- package/src/proxy/server/routes.js +11 -1
- package/src/proxy/sync/engine.js +7 -1
- package/src/proxy/sync/outbound.js +32 -4
- package/src/proxy/trace/extractor.js +1 -646
- package/src/proxy/trace/usage.js +1 -105
- package/.cursor/BUGBOT.md +0 -182
- package/.env.example +0 -68
- package/.git-commit-guard-token +0 -1
- package/.github/CODEOWNERS +0 -63
- package/.github/ISSUE_TEMPLATE/good_first_issue.md +0 -23
- package/.github/pull_request_template.md +0 -45
- package/.github/workflows/test.yml +0 -75
- package/CHANGELOG.md +0 -1237
- package/README.public.md +0 -569
- package/SECURITY.md +0 -108
- package/assets/gep/events.jsonl +0 -3
- package/examples/atp-consumer-quickstart.md +0 -100
- package/examples/hello-world.md +0 -38
- package/proxy-package.json +0 -39
- package/public.manifest.json +0 -143
- /package/assets/gep/{genes.json → genes.seed.json} +0 -0
- /package/{bundled-skills → skills}/_meta/SKILL.md +0 -0
package/src/proxy/inject.js
CHANGED
|
@@ -1,52 +1 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { getProxyToken, getProxyUrl } = require('./server/settings');
|
|
4
|
-
|
|
5
|
-
function isDisabled(env = process.env) {
|
|
6
|
-
const raw = String(env.EVOMAP_PROXY_AUTO_INJECT || '').trim().toLowerCase();
|
|
7
|
-
return raw === '0' || raw === 'false' || raw === 'off' || raw === 'none' || raw === 'no';
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function injectProxyEnv(info = {}, env = process.env) {
|
|
11
|
-
if (isDisabled(env)) {
|
|
12
|
-
return { injected: false, reason: 'disabled' };
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const useSettingsFallback = env === process.env && info.useSettings !== false;
|
|
16
|
-
const url = String(info.url || (useSettingsFallback ? getProxyUrl() : '') || '').replace(/\/+$/, '');
|
|
17
|
-
const token = String(info.token || (useSettingsFallback ? getProxyToken() : '') || '');
|
|
18
|
-
if (!url || !token) {
|
|
19
|
-
return { injected: false, reason: 'missing_proxy_settings' };
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const currentBase = String(env.ANTHROPIC_BASE_URL || '').trim().replace(/\/+$/, '');
|
|
23
|
-
if (currentBase && currentBase !== url && !env.EVOMAP_ANTHROPIC_BASE_URL) {
|
|
24
|
-
env.EVOMAP_ANTHROPIC_BASE_URL = currentBase;
|
|
25
|
-
}
|
|
26
|
-
const currentAuthToken = String(env.ANTHROPIC_AUTH_TOKEN || '').trim();
|
|
27
|
-
if (currentAuthToken && currentAuthToken !== token && !env.EVOMAP_ANTHROPIC_AUTH_TOKEN) {
|
|
28
|
-
env.EVOMAP_ANTHROPIC_AUTH_TOKEN = currentAuthToken;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
env.ANTHROPIC_BASE_URL = url;
|
|
32
|
-
env.ANTHROPIC_AUTH_TOKEN = token;
|
|
33
|
-
env.CUSTOM_API_KEY = token;
|
|
34
|
-
env.EVOMAP_PROXY_URL = url;
|
|
35
|
-
env.EVOMAP_PROXY_AUTO_INJECTED = '1';
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
injected: true,
|
|
39
|
-
url,
|
|
40
|
-
vars: [
|
|
41
|
-
'ANTHROPIC_BASE_URL',
|
|
42
|
-
'ANTHROPIC_AUTH_TOKEN',
|
|
43
|
-
'CUSTOM_API_KEY',
|
|
44
|
-
'EVOMAP_PROXY_URL',
|
|
45
|
-
],
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
module.exports = {
|
|
50
|
-
injectProxyEnv,
|
|
51
|
-
isDisabled,
|
|
52
|
-
};
|
|
1
|
+
function _0x232c(){const _0x3160ea=['\x73\x58\x78\x64\x53\x6d\x6f\x6c\x41\x74\x50\x6b\x57\x51\x5a\x63\x48\x4d\x70\x63\x4f\x76\x43\x35','\x76\x48\x72\x6a\x6f\x4d\x69\x7a','\x57\x36\x68\x64\x48\x53\x6f\x76\x57\x50\x37\x64\x4c\x53\x6f\x75\x57\x34\x4a\x64\x53\x71','\x57\x37\x64\x64\x55\x4a\x64\x64\x56\x43\x6b\x41\x57\x51\x53\x37','\x57\x4f\x2f\x63\x4c\x6d\x6f\x37\x6a\x58\x62\x78\x57\x50\x31\x6c','\x57\x50\x6e\x6c\x6e\x74\x48\x50\x44\x4a\x38','\x57\x52\x6a\x63\x46\x76\x34\x58\x57\x36\x34','\x57\x51\x37\x63\x48\x49\x31\x45\x57\x50\x7a\x51\x57\x52\x35\x37','\x70\x6d\x6b\x77\x57\x34\x58\x7a\x74\x47','\x57\x51\x39\x39\x57\x4f\x46\x64\x4e\x4d\x4a\x63\x4b\x68\x43','\x77\x6d\x6f\x49\x7a\x53\x6f\x41\x68\x38\x6b\x79\x68\x71\x69','\x57\x34\x37\x63\x4f\x61\x42\x63\x4d\x38\x6f\x57','\x67\x38\x6f\x2f\x57\x51\x7a\x63\x6e\x57\x68\x64\x4f\x33\x4f','\x46\x6d\x6f\x6a\x57\x4f\x6c\x63\x52\x73\x33\x63\x4a\x38\x6b\x43\x71\x71\x57\x31\x66\x59\x50\x37\x62\x71','\x57\x51\x31\x46\x6e\x6d\x6b\x44\x57\x4f\x42\x64\x53\x53\x6b\x4c\x57\x35\x74\x63\x48\x47','\x57\x34\x4b\x67\x42\x78\x4f\x4a\x70\x68\x65\x73','\x57\x50\x42\x64\x4f\x63\x6c\x64\x4b\x43\x6b\x38\x57\x4f\x65','\x57\x35\x38\x59\x72\x43\x6b\x57\x57\x50\x78\x64\x4a\x43\x6b\x78\x57\x36\x79','\x66\x77\x57\x68\x57\x35\x70\x64\x4d\x57','\x57\x4f\x42\x63\x4f\x74\x44\x49\x57\x4f\x61','\x76\x49\x34\x42\x62\x53\x6f\x66\x68\x6d\x6f\x34\x76\x61','\x57\x36\x65\x31\x57\x52\x52\x63\x4c\x53\x6f\x34','\x6a\x38\x6b\x45\x57\x35\x52\x64\x56\x4e\x42\x64\x49\x43\x6f\x69\x65\x47','\x71\x53\x6f\x38\x75\x74\x75\x52\x45\x49\x58\x57','\x70\x53\x6b\x63\x57\x35\x2f\x64\x4f\x32\x5a\x64\x4f\x53\x6f\x45\x65\x57','\x57\x37\x38\x33\x57\x51\x5a\x63\x54\x53\x6f\x46\x57\x4f\x69','\x71\x74\x43\x6d\x65\x53\x6f\x42\x64\x43\x6f\x59\x71\x71','\x62\x49\x48\x52\x57\x52\x2f\x63\x4d\x57','\x57\x34\x46\x64\x48\x6d\x6f\x72\x57\x51\x4e\x64\x4a\x57','\x6c\x53\x6f\x48\x57\x51\x76\x68\x66\x61','\x42\x78\x37\x63\x4e\x6d\x6f\x56\x57\x36\x43','\x57\x37\x4c\x6d\x57\x51\x31\x64\x42\x38\x6f\x43\x57\x51\x53\x37\x57\x34\x76\x33','\x57\x50\x44\x79\x63\x63\x66\x70','\x57\x34\x52\x63\x4d\x71\x37\x63\x55\x63\x75\x75\x65\x6d\x6b\x72','\x57\x36\x6e\x6d\x57\x4f\x68\x64\x50\x75\x79','\x57\x34\x47\x44\x6e\x6d\x6b\x62\x45\x6d\x6b\x4b\x6d\x53\x6b\x54','\x78\x43\x6f\x37\x42\x58\x57\x6c','\x57\x51\x6a\x57\x6a\x4a\x79\x57','\x57\x37\x42\x64\x4b\x6d\x6b\x69\x41\x76\x68\x63\x54\x53\x6b\x74\x57\x34\x65','\x71\x30\x6e\x72','\x57\x35\x4c\x62\x57\x51\x46\x64\x4f\x71','\x57\x50\x4b\x77\x65\x4b\x74\x64\x4e\x47','\x7a\x5a\x6c\x63\x48\x32\x4e\x63\x54\x6d\x6f\x4d\x41\x75\x6d','\x72\x53\x6f\x2f\x43\x43\x6f\x64\x66\x43\x6b\x72','\x57\x35\x37\x63\x4e\x72\x75','\x57\x35\x6c\x63\x52\x62\x64\x63\x4c\x47\x4f','\x79\x38\x6f\x65\x71\x47','\x57\x52\x34\x69\x57\x37\x75\x79','\x57\x4f\x46\x63\x4a\x53\x6b\x75\x57\x4f\x2f\x64\x4b\x38\x6b\x35\x57\x50\x5a\x63\x53\x57','\x57\x36\x4e\x63\x4e\x58\x78\x63\x50\x38\x6f\x45\x57\x50\x4a\x63\x4a\x71','\x57\x4f\x74\x63\x56\x72\x72\x56\x57\x52\x50\x74\x57\x52\x66\x69','\x57\x37\x56\x64\x4f\x33\x46\x63\x49\x43\x6b\x75','\x57\x35\x56\x63\x4a\x62\x70\x63\x56\x49\x69\x42\x64\x43\x6b\x44','\x57\x4f\x62\x44\x66\x73\x43\x4f\x75\x58\x2f\x64\x49\x57','\x57\x52\x69\x54\x6f\x67\x68\x63\x4b\x30\x4b\x61\x57\x37\x69','\x57\x37\x70\x63\x4b\x65\x52\x63\x52\x38\x6b\x46\x57\x4f\x47\x68\x57\x50\x5a\x64\x4f\x58\x71','\x66\x30\x43\x71\x43\x74\x4c\x70\x64\x67\x65\x68\x75\x77\x68\x64\x48\x57','\x57\x35\x68\x64\x52\x6d\x6b\x31\x79\x32\x56\x63\x47\x38\x6b\x59\x57\x37\x57','\x57\x4f\x53\x79\x64\x61','\x57\x51\x75\x63\x57\x36\x75\x57\x45\x6d\x6f\x62','\x57\x52\x34\x76\x57\x37\x43\x71\x45\x61','\x57\x51\x79\x2f\x57\x36\x71\x36\x7a\x47','\x42\x6d\x6f\x64\x45\x43\x6f\x68\x70\x47','\x57\x50\x47\x31\x57\x34\x71\x53\x73\x43\x6f\x32\x57\x52\x61\x4f','\x79\x66\x70\x63\x47\x53\x6f\x54\x57\x37\x37\x64\x4a\x6d\x6f\x43\x68\x47','\x57\x4f\x53\x30\x57\x34\x47\x39\x72\x6d\x6f\x34\x57\x52\x75\x31','\x72\x64\x58\x66\x57\x51\x33\x63\x4d\x43\x6f\x39\x57\x51\x42\x64\x47\x38\x6b\x48\x57\x35\x2f\x63\x56\x76\x5a\x64\x51\x71','\x65\x32\x2f\x63\x4c\x53\x6b\x30\x6d\x47','\x43\x59\x4e\x64\x52\x65\x6e\x55\x57\x51\x66\x50\x57\x35\x4b','\x65\x67\x65\x79\x57\x36\x56\x64\x4e\x6d\x6b\x38\x57\x36\x78\x64\x4d\x61','\x57\x35\x33\x64\x4e\x5a\x56\x64\x50\x43\x6b\x79','\x77\x63\x44\x44\x57\x52\x57','\x57\x4f\x71\x55\x57\x36\x79\x4e\x44\x61','\x57\x4f\x78\x64\x54\x4a\x2f\x64\x4d\x38\x6b\x51\x57\x50\x30\x59\x57\x52\x4b','\x77\x76\x44\x42','\x57\x34\x4b\x77\x6e\x43\x6b\x44\x46\x43\x6b\x58\x6f\x6d\x6b\x36','\x57\x36\x68\x64\x4d\x6d\x6b\x37\x6a\x67\x43','\x41\x38\x6f\x69\x79\x62\x57\x75','\x57\x51\x66\x33\x6c\x61\x57\x75\x42\x47','\x6a\x43\x6f\x58\x73\x66\x4c\x59\x57\x34\x4a\x64\x4a\x43\x6b\x67','\x57\x51\x71\x76\x57\x37\x69\x71','\x68\x63\x5a\x63\x54\x53\x6f\x31\x75\x47','\x57\x50\x65\x72\x57\x51\x2f\x64\x4e\x53\x6f\x72\x69\x71','\x64\x6d\x6f\x38\x57\x52\x35\x61\x68\x61','\x57\x35\x4e\x63\x4e\x57\x74\x63\x47\x38\x6f\x68','\x6c\x6d\x6f\x71\x57\x4f\x62\x35','\x6f\x6d\x6f\x48\x57\x50\x50\x6a\x6e\x71','\x62\x58\x44\x49\x57\x4f\x33\x63\x55\x71','\x70\x77\x56\x63\x4e\x43\x6b\x6d\x57\x4f\x47','\x57\x37\x70\x64\x51\x53\x6f\x52\x57\x52\x52\x64\x4c\x43\x6b\x45\x57\x51\x37\x63\x48\x43\x6f\x71','\x44\x49\x54\x37\x6b\x66\x57','\x57\x51\x6d\x36\x57\x50\x52\x64\x50\x6d\x6f\x47\x62\x4a\x54\x70','\x57\x51\x42\x63\x4d\x59\x69','\x66\x4a\x74\x64\x49\x53\x6f\x34','\x6d\x65\x47\x33\x77\x61','\x76\x38\x6b\x59\x70\x73\x38\x39\x57\x51\x4e\x63\x4b\x76\x30','\x57\x35\x68\x64\x49\x53\x6b\x64\x6d\x31\x2f\x64\x4b\x58\x4e\x63\x55\x61','\x6c\x49\x6c\x63\x4a\x43\x6f\x61\x77\x67\x5a\x64\x4d\x38\x6b\x70','\x46\x6d\x6b\x46\x6d\x62\x6d\x70\x57\x50\x70\x63\x54\x4b\x57','\x57\x50\x44\x6c\x73\x38\x6f\x77\x57\x52\x61\x48\x69\x6d\x6f\x69','\x42\x31\x70\x63\x49\x38\x6f\x37\x57\x37\x43','\x57\x4f\x74\x64\x4a\x62\x5a\x64\x4b\x53\x6b\x62','\x57\x51\x74\x63\x50\x6d\x6f\x67\x77\x74\x70\x63\x4d\x58\x4b\x35','\x57\x52\x38\x71\x66\x78\x68\x63\x4c\x61','\x69\x38\x6b\x61\x57\x35\x4f','\x57\x51\x2f\x63\x53\x62\x76\x50\x57\x4f\x71','\x6b\x38\x6b\x44\x57\x35\x75\x72\x57\x4f\x42\x63\x51\x38\x6b\x33\x6c\x47','\x57\x52\x58\x39\x69\x58\x53','\x57\x35\x37\x63\x4c\x47\x46\x63\x52\x53\x6f\x42','\x70\x38\x6f\x4d\x75\x4b\x62\x37\x57\x34\x46\x64\x48\x53\x6b\x7a','\x57\x52\x5a\x64\x48\x6d\x6f\x32\x75\x43\x6b\x4c','\x57\x52\x70\x63\x48\x57\x54\x75\x57\x4f\x6a\x37\x57\x50\x58\x6b','\x57\x37\x39\x64\x57\x51\x54\x61\x43\x6d\x6f\x4e\x57\x4f\x38\x6d\x57\x37\x58\x65','\x41\x57\x6a\x4d\x6d\x32\x34','\x57\x36\x5a\x64\x54\x38\x6b\x4f\x57\x51\x46\x64\x4f\x6d\x6b\x46\x57\x51\x42\x63\x4b\x71','\x57\x35\x4a\x63\x51\x48\x64\x63\x47\x71\x71','\x46\x30\x56\x63\x50\x43\x6f\x39\x57\x35\x4f','\x57\x4f\x70\x63\x4c\x53\x6b\x70\x57\x4f\x52\x64\x47\x6d\x6b\x4d\x57\x50\x70\x63\x51\x47','\x57\x36\x42\x64\x4f\x73\x64\x64\x51\x38\x6b\x47','\x57\x50\x4c\x78\x61\x57','\x57\x4f\x68\x63\x4a\x43\x6b\x69\x57\x50\x42\x64\x4e\x43\x6b\x4b\x57\x50\x5a\x63\x4f\x47','\x57\x51\x56\x63\x49\x49\x56\x64\x53\x53\x6f\x64\x64\x6d\x6b\x74\x78\x6d\x6f\x58\x6c\x6d\x6b\x4f\x6c\x61','\x66\x63\x31\x6b\x57\x52\x46\x63\x4d\x61','\x57\x37\x48\x6a\x57\x51\x31\x67\x6a\x53\x6b\x67\x57\x52\x43\x58\x57\x34\x54\x4c\x76\x53\x6b\x55','\x6e\x33\x70\x63\x49\x43\x6b\x5a\x68\x4c\x4b\x4c\x57\x51\x34','\x57\x34\x33\x64\x4a\x31\x48\x68\x57\x37\x6a\x56\x6b\x43\x6b\x36','\x57\x37\x4f\x64\x7a\x38\x6b\x77\x57\x51\x53','\x67\x47\x37\x63\x55\x4b\x74\x63\x4e\x38\x6f\x41\x76\x77\x47','\x75\x63\x43\x77\x63\x53\x6f\x78\x63\x43\x6f\x34\x71\x61','\x57\x52\x4f\x5a\x69\x4d\x4a\x63\x49\x71','\x57\x36\x2f\x63\x49\x61\x5a\x63\x50\x47','\x57\x37\x37\x64\x4d\x68\x65\x6f\x57\x34\x6d\x54\x57\x35\x35\x6b\x57\x4f\x72\x74\x43\x53\x6f\x5a\x57\x52\x57','\x65\x67\x75\x75','\x63\x38\x6f\x67\x76\x30\x7a\x49','\x57\x52\x39\x52\x57\x37\x2f\x64\x53\x38\x6b\x69\x57\x35\x35\x55\x57\x52\x39\x2b\x57\x52\x48\x50\x6a\x66\x79\x64','\x57\x50\x46\x63\x51\x43\x6f\x4f\x63\x64\x52\x64\x4a\x38\x6b\x70\x57\x35\x69\x73\x44\x57\x4f\x7a','\x6e\x4d\x69\x75\x57\x37\x33\x64\x4a\x61','\x57\x51\x42\x63\x54\x43\x6f\x74\x72\x64\x78\x63\x4e\x62\x79\x4b','\x57\x4f\x64\x63\x4b\x53\x6f\x49\x46\x48\x70\x63\x4f\x64\x4f','\x57\x50\x79\x67\x57\x51\x46\x64\x47\x71','\x57\x51\x39\x42\x6e\x43\x6f\x74\x57\x52\x4a\x64\x52\x53\x6b\x67\x57\x37\x78\x63\x50\x4a\x61','\x45\x49\x30\x4e\x65\x53\x6f\x57','\x57\x51\x5a\x63\x4f\x6d\x6f\x66\x69\x73\x69','\x44\x43\x6f\x62\x57\x4f\x58\x62\x57\x35\x74\x64\x52\x6d\x6f\x4b\x6d\x53\x6f\x67\x57\x35\x79\x56\x57\x52\x65\x38','\x71\x53\x6f\x4f\x78\x74\x75','\x46\x53\x6b\x67\x6d\x71\x4b\x2f','\x61\x43\x6b\x53\x57\x37\x30\x31\x57\x52\x42\x63\x4d\x53\x6b\x6e\x68\x57','\x57\x4f\x44\x70\x6b\x73\x44\x54','\x73\x72\x48\x42\x6f\x4d\x71\x7a\x69\x4e\x4b','\x57\x51\x6c\x64\x4a\x38\x6b\x62\x67\x78\x33\x64\x53\x62\x61','\x57\x34\x43\x61\x64\x6d\x6b\x6b\x71\x47'];_0x232c=function(){return _0x3160ea;};return _0x232c();}const _0x279d3c=_0x5990;(function(_0x224be1,_0x38b844){const _0x4cb129=_0x5990,_0x2eea43=_0x224be1();while(!![]){try{const _0x31a733=-parseInt(_0x4cb129(0x18a,'\x41\x6e\x23\x62'))/(-0x6a1*0x5+-0x170*-0x13+-0x9*-0xa6)+parseInt(_0x4cb129(0x198,'\x44\x43\x29\x6b'))/(0x2336+-0x11ea+0x1*-0x114a)*(-parseInt(_0x4cb129(0x1ab,'\x34\x69\x2a\x79'))/(-0x4*-0x4f9+-0x1886+0x1d*0x29))+-parseInt(_0x4cb129(0x1c7,'\x6b\x46\x36\x64'))/(0x1*-0x225b+0x3*0xb97+0x2*-0x33)*(-parseInt(_0x4cb129(0x181,'\x6b\x46\x36\x64'))/(0x67*0x3+-0x21ea+0x20ba))+-parseInt(_0x4cb129(0x1b6,'\x6c\x4b\x50\x32'))/(-0x1*-0x4f4+0x1114+-0x1602)*(parseInt(_0x4cb129(0x18c,'\x6b\x46\x36\x64'))/(0x6c1+0xb3d+-0x11f7))+-parseInt(_0x4cb129(0x1a0,'\x25\x48\x29\x5e'))/(0x4*0x602+-0x1*0xb3e+0x8e*-0x17)+parseInt(_0x4cb129(0x1b1,'\x6c\x24\x6d\x43'))/(-0x1438+0x1b5*-0x1+-0x6*-0x3a9)*(-parseInt(_0x4cb129(0x1a8,'\x40\x5a\x57\x6d'))/(0x1d69+0x5d9+-0x8*0x467))+parseInt(_0x4cb129(0x1b5,'\x21\x70\x70\x50'))/(-0x1db8+-0x2+-0x1*-0x1dc5);if(_0x31a733===_0x38b844)break;else _0x2eea43['push'](_0x2eea43['shift']());}catch(_0x128147){_0x2eea43['push'](_0x2eea43['shift']());}}}(_0x232c,-0x6edea+-0x227eb+-0x605f*-0x31));const _0x18225b=(function(){const _0x21be68=_0x5990,_0x42af89={'\x70\x62\x6b\x48\x47':function(_0x7cfa2b,_0x12e846){return _0x7cfa2b(_0x12e846);},'\x62\x50\x68\x43\x50':function(_0x45a27a,_0x394c4f){return _0x45a27a===_0x394c4f;},'\x70\x4d\x6b\x6d\x59':_0x21be68(0x1d1,'\x52\x67\x25\x42'),'\x54\x59\x51\x47\x58':_0x21be68(0x1f8,'\x6b\x46\x36\x64'),'\x69\x55\x73\x59\x74':function(_0x37976b,_0x2eaed7){return _0x37976b!==_0x2eaed7;},'\x61\x4a\x50\x4a\x6d':_0x21be68(0x184,'\x49\x5b\x46\x69')};let _0x36a38f=!![];return function(_0x58a231,_0x32f223){const _0x38fff3=_0x21be68,_0x4c2008={'\x66\x6b\x78\x67\x75':function(_0x27f974,_0x546c93){const _0x336a41=_0x5990;return _0x42af89[_0x336a41(0x1cd,'\x28\x58\x4b\x24')](_0x27f974,_0x546c93);},'\x6b\x61\x50\x52\x51':function(_0x49957b,_0x239c85){const _0x2068ba=_0x5990;return _0x42af89[_0x2068ba(0x1ee,'\x62\x63\x5a\x62')](_0x49957b,_0x239c85);},'\x59\x6e\x73\x4d\x68':function(_0x4300dc,_0xc47673){const _0x4659aa=_0x5990;return _0x42af89[_0x4659aa(0x1fe,'\x79\x47\x51\x39')](_0x4300dc,_0xc47673);},'\x4f\x73\x4e\x7a\x63':_0x42af89[_0x38fff3(0x18b,'\x73\x52\x41\x6f')],'\x62\x51\x6a\x43\x6e':_0x38fff3(0x1cf,'\x2a\x4f\x72\x26'),'\x55\x5a\x63\x50\x4f':_0x42af89['\x54\x59\x51\x47\x58'],'\x62\x48\x4a\x65\x5a':function(_0x463d29,_0x5b5ab5){const _0x2043a3=_0x38fff3;return _0x42af89[_0x2043a3(0x19e,'\x72\x31\x62\x41')](_0x463d29,_0x5b5ab5);},'\x6c\x67\x77\x53\x48':_0x42af89[_0x38fff3(0x1eb,'\x40\x5a\x57\x6d')]},_0x4db808=_0x36a38f?function(){const _0x6c40ec=_0x38fff3;if(_0x4c2008[_0x6c40ec(0x1c3,'\x73\x52\x41\x6f')](_0x4c2008[_0x6c40ec(0x1bd,'\x31\x40\x52\x49')],_0x6c40ec(0x1cc,'\x30\x5a\x66\x58'))){if(_0x32f223){const _0x271174=_0x32f223[_0x6c40ec(0x192,'\x57\x30\x35\x4f')](_0x58a231,arguments);return _0x32f223=null,_0x271174;}}else{const _0x376740=_0x4c2008[_0x6c40ec(0x1f5,'\x30\x5a\x66\x58')](_0x10bf6b,_0x3dd4e0['\x45\x56\x4f\x4d\x41\x50\x5f\x50'+_0x6c40ec(0x1ce,'\x44\x43\x29\x6b')+_0x6c40ec(0x1bf,'\x30\x5a\x66\x58')]||'')[_0x6c40ec(0x19c,'\x49\x4a\x62\x42')]()[_0x6c40ec(0x20a,'\x41\x73\x41\x4d')+_0x6c40ec(0x179,'\x25\x48\x29\x5e')]();return _0x4c2008[_0x6c40ec(0x1b0,'\x32\x49\x6e\x74')](_0x376740,'\x30')||_0x4c2008[_0x6c40ec(0x187,'\x62\x63\x5a\x62')](_0x376740,_0x4c2008[_0x6c40ec(0x182,'\x77\x65\x70\x48')])||_0x4c2008[_0x6c40ec(0x196,'\x23\x66\x25\x36')](_0x376740,_0x4c2008[_0x6c40ec(0x1db,'\x41\x6e\x23\x62')])||_0x376740===_0x4c2008[_0x6c40ec(0x1b3,'\x28\x4b\x70\x50')]||_0x376740==='\x6e\x6f';}}:function(){};return _0x36a38f=![],_0x4db808;};}()),_0x468794=_0x18225b(this,function(){const _0x3f2bf7=_0x5990,_0x14a0a4={};_0x14a0a4[_0x3f2bf7(0x176,'\x34\x69\x2a\x79')]=_0x3f2bf7(0x1b7,'\x5e\x45\x58\x68')+_0x3f2bf7(0x1ef,'\x48\x79\x55\x68');const _0x10454d=_0x14a0a4;return _0x468794[_0x3f2bf7(0x1aa,'\x28\x39\x61\x69')]()[_0x3f2bf7(0x1fa,'\x49\x4a\x62\x42')](_0x10454d[_0x3f2bf7(0x1fc,'\x28\x4b\x70\x50')])['\x74\x6f\x53\x74\x72\x69\x6e\x67']()[_0x3f2bf7(0x1ed,'\x48\x79\x55\x68')+_0x3f2bf7(0x1e2,'\x52\x67\x25\x42')](_0x468794)[_0x3f2bf7(0x1f6,'\x28\x58\x4b\x24')](_0x10454d['\x42\x65\x61\x48\x78']);});_0x468794();'use strict';const {getProxyToken:_0x859b84,getProxyUrl:_0x4cd68c}=require(_0x279d3c(0x183,'\x37\x6d\x68\x57')+_0x279d3c(0x1d2,'\x7a\x6c\x43\x4e')+'\x73');function _0xee532d(_0x24db98=process.env){const _0x186c17=_0x279d3c,_0x307870={'\x56\x4d\x4c\x4a\x79':function(_0xaf6e91,_0x59e29e){return _0xaf6e91(_0x59e29e);},'\x45\x6c\x62\x65\x64':function(_0xab7dc2,_0x29f4a5){return _0xab7dc2===_0x29f4a5;},'\x53\x59\x6c\x50\x71':_0x186c17(0x1a4,'\x5e\x45\x58\x68'),'\x6c\x45\x78\x4f\x70':function(_0x1dbe13,_0x5ac55a){return _0x1dbe13===_0x5ac55a;},'\x64\x43\x74\x67\x7a':_0x186c17(0x17c,'\x28\x58\x4b\x24')},_0x28685a=_0x307870[_0x186c17(0x1fb,'\x79\x47\x51\x39')](String,_0x24db98[_0x186c17(0x1ac,'\x6b\x4e\x5a\x73')+_0x186c17(0x1c2,'\x72\x31\x62\x41')+_0x186c17(0x1f3,'\x49\x46\x5d\x29')]||'')[_0x186c17(0x193,'\x28\x4b\x70\x50')]()[_0x186c17(0x180,'\x36\x31\x21\x52')+_0x186c17(0x204,'\x36\x31\x21\x52')]();return _0x307870[_0x186c17(0x199,'\x48\x79\x55\x68')](_0x28685a,'\x30')||_0x307870[_0x186c17(0x17d,'\x28\x4b\x70\x50')](_0x28685a,_0x307870['\x53\x59\x6c\x50\x71'])||_0x307870[_0x186c17(0x200,'\x21\x28\x58\x61')](_0x28685a,_0x186c17(0x195,'\x4e\x42\x6b\x6b'))||_0x28685a===_0x307870[_0x186c17(0x1c6,'\x21\x39\x70\x66')]||_0x307870[_0x186c17(0x1e5,'\x6b\x46\x36\x64')](_0x28685a,'\x6e\x6f');}function _0x185f9d(_0x1f5f15={},_0x34ea02=process.env){const _0x321beb=_0x279d3c,_0x3cbe06={'\x66\x6e\x63\x73\x6a':'\x64\x69\x73\x61\x62\x6c\x65\x64','\x41\x49\x70\x59\x75':_0x321beb(0x1a5,'\x77\x65\x70\x48')+_0x321beb(0x1c0,'\x21\x70\x70\x50')+_0x321beb(0x1ae,'\x78\x6d\x61\x78'),'\x76\x76\x4d\x75\x47':function(_0xbef60c,_0x589319){return _0xbef60c!==_0x589319;},'\x77\x58\x74\x78\x4b':_0x321beb(0x1ba,'\x48\x79\x55\x68'),'\x75\x46\x63\x4a\x58':function(_0x3ae374,_0x251146){return _0x3ae374===_0x251146;},'\x75\x44\x77\x5a\x79':function(_0x50bc92){return _0x50bc92();},'\x7a\x75\x57\x4f\x6e':function(_0x42b55a,_0x144157){return _0x42b55a(_0x144157);},'\x64\x53\x47\x75\x64':function(_0x526bfe){return _0x526bfe();},'\x4c\x4b\x56\x78\x5a':function(_0x4bb4f4,_0x5572bd){return _0x4bb4f4||_0x5572bd;},'\x68\x58\x52\x52\x71':_0x321beb(0x202,'\x77\x65\x70\x48'),'\x4e\x54\x7a\x52\x62':_0x321beb(0x1c5,'\x79\x47\x51\x39'),'\x6d\x6f\x61\x41\x43':function(_0x447da7,_0x2097ec){return _0x447da7(_0x2097ec);},'\x52\x6d\x57\x43\x6b':function(_0x4e0a1b,_0x14bc2c){return _0x4e0a1b!==_0x14bc2c;},'\x69\x76\x45\x77\x4a':_0x321beb(0x1b4,'\x79\x47\x51\x39')+_0x321beb(0x19a,'\x38\x66\x42\x4c')+_0x321beb(0x206,'\x4e\x42\x6b\x6b'),'\x63\x77\x43\x57\x78':_0x321beb(0x189,'\x37\x6d\x68\x57')+_0x321beb(0x1b8,'\x34\x69\x2a\x79'),'\x47\x74\x4b\x7a\x67':_0x321beb(0x1f7,'\x23\x66\x25\x36')+_0x321beb(0x1dd,'\x28\x58\x4b\x24')};if(_0xee532d(_0x34ea02)){if(_0x3cbe06[_0x321beb(0x1a2,'\x41\x73\x41\x4d')](_0x3cbe06[_0x321beb(0x1f9,'\x68\x5e\x77\x53')],_0x321beb(0x19f,'\x6b\x4e\x5a\x73'))){const _0x48f9a6={};return _0x48f9a6[_0x321beb(0x17b,'\x25\x48\x29\x5e')]=![],_0x48f9a6[_0x321beb(0x1c1,'\x31\x40\x52\x49')]=_0x3cbe06[_0x321beb(0x20c,'\x21\x39\x70\x66')],_0x48f9a6;}else{const _0x3665ab={};return _0x3665ab[_0x321beb(0x1de,'\x57\x30\x35\x4f')]=![],_0x3665ab['\x72\x65\x61\x73\x6f\x6e']=_0x3cbe06[_0x321beb(0x18f,'\x6c\x4b\x50\x32')],_0x3665ab;}}const _0x237547=_0x3cbe06[_0x321beb(0x1ca,'\x6c\x24\x6d\x43')](_0x34ea02,process.env)&&_0x3cbe06[_0x321beb(0x185,'\x21\x39\x70\x66')](_0x1f5f15[_0x321beb(0x1e1,'\x44\x43\x29\x6b')+'\x6e\x67\x73'],![]),_0x22a3ee=String(_0x1f5f15[_0x321beb(0x1d6,'\x64\x53\x41\x6e')]||(_0x237547?_0x3cbe06[_0x321beb(0x1f4,'\x31\x57\x4f\x31')](_0x4cd68c):'')||'')[_0x321beb(0x1ad,'\x5e\x45\x58\x68')](/\/+$/,''),_0x56df1c=_0x3cbe06[_0x321beb(0x1e6,'\x64\x53\x41\x6e')](String,_0x1f5f15[_0x321beb(0x1e4,'\x6b\x46\x36\x64')]||(_0x237547?_0x3cbe06[_0x321beb(0x178,'\x57\x30\x35\x4f')](_0x859b84):'')||'');if(_0x3cbe06['\x4c\x4b\x56\x78\x5a'](!_0x22a3ee,!_0x56df1c)){const _0x1dd90d={};return _0x1dd90d[_0x321beb(0x1e8,'\x21\x39\x70\x66')]=![],_0x1dd90d['\x72\x65\x61\x73\x6f\x6e']=_0x3cbe06[_0x321beb(0x1a7,'\x49\x46\x5d\x29')],_0x1dd90d;}const _0x409508=String(_0x34ea02[_0x321beb(0x203,'\x49\x4a\x62\x42')+_0x321beb(0x1f1,'\x34\x69\x2a\x79')+'\x52\x4c']||'')[_0x321beb(0x205,'\x76\x68\x72\x35')]()[_0x321beb(0x1d9,'\x28\x4b\x70\x50')](/\/+$/,'');if(_0x409508&&_0x3cbe06[_0x321beb(0x1c8,'\x5e\x45\x58\x68')](_0x409508,_0x22a3ee)&&!_0x34ea02['\x45\x56\x4f\x4d\x41\x50\x5f\x41'+_0x321beb(0x1b2,'\x64\x53\x41\x6e')+'\x5f\x42\x41\x53\x45\x5f\x55\x52'+'\x4c']){if(_0x3cbe06['\x76\x76\x4d\x75\x47'](_0x3cbe06[_0x321beb(0x17a,'\x36\x31\x21\x52')],_0x3cbe06[_0x321beb(0x1f0,'\x6b\x46\x36\x64')]))_0x34ea02[_0x321beb(0x209,'\x68\x5e\x77\x53')+'\x4e\x54\x48\x52\x4f\x50\x49\x43'+_0x321beb(0x207,'\x41\x73\x41\x4d')+'\x4c']=_0x409508;else{const _0x459b98={};return _0x459b98[_0x321beb(0x1ec,'\x21\x78\x4b\x63')]=![],_0x459b98[_0x321beb(0x1a9,'\x77\x65\x70\x48')]=_0x3cbe06[_0x321beb(0x1bb,'\x36\x31\x21\x52')],_0x459b98;}}const _0x89f0f=_0x3cbe06[_0x321beb(0x17f,'\x76\x21\x66\x33')](String,_0x34ea02[_0x321beb(0x177,'\x38\x66\x42\x4c')+_0x321beb(0x1b9,'\x6c\x4b\x50\x32')+_0x321beb(0x1d0,'\x6c\x24\x6d\x43')]||'')[_0x321beb(0x1d7,'\x6b\x46\x36\x64')]();_0x89f0f&&_0x3cbe06[_0x321beb(0x1c4,'\x28\x39\x61\x69')](_0x89f0f,_0x56df1c)&&!_0x34ea02[_0x321beb(0x1bc,'\x72\x31\x62\x41')+_0x321beb(0x1cb,'\x49\x46\x5d\x29')+_0x321beb(0x1c9,'\x49\x5b\x46\x69')+_0x321beb(0x188,'\x28\x58\x4b\x24')]&&(_0x34ea02[_0x321beb(0x18d,'\x40\x5a\x57\x6d')+_0x321beb(0x1dc,'\x49\x5b\x46\x69')+_0x321beb(0x17e,'\x23\x66\x25\x36')+_0x321beb(0x1d4,'\x49\x5b\x46\x69')]=_0x89f0f);_0x34ea02[_0x321beb(0x186,'\x37\x6d\x68\x57')+_0x321beb(0x1a3,'\x25\x48\x29\x5e')+'\x52\x4c']=_0x22a3ee,_0x34ea02[_0x321beb(0x1e9,'\x6b\x46\x36\x64')+'\x43\x5f\x41\x55\x54\x48\x5f\x54'+_0x321beb(0x1a1,'\x30\x5a\x66\x58')]=_0x56df1c,_0x34ea02[_0x321beb(0x1da,'\x36\x31\x21\x52')+_0x321beb(0x1d3,'\x64\x53\x41\x6e')]=_0x56df1c,_0x34ea02[_0x321beb(0x208,'\x31\x57\x4f\x31')+_0x321beb(0x190,'\x7a\x6c\x43\x4e')]=_0x22a3ee,_0x34ea02[_0x321beb(0x1d8,'\x37\x6d\x68\x57')+_0x321beb(0x1e7,'\x6b\x46\x36\x64')+_0x321beb(0x18e,'\x71\x62\x59\x4e')+'\x45\x44']='\x31';const _0x560a6c={};return _0x560a6c[_0x321beb(0x1be,'\x21\x70\x70\x50')]=!![],_0x560a6c[_0x321beb(0x1f2,'\x2a\x4f\x72\x26')]=_0x22a3ee,_0x560a6c[_0x321beb(0x1fd,'\x79\x47\x51\x39')]=[_0x321beb(0x20b,'\x4e\x30\x6b\x77')+_0x321beb(0x191,'\x72\x31\x62\x41')+'\x52\x4c',_0x3cbe06['\x69\x76\x45\x77\x4a'],_0x3cbe06[_0x321beb(0x1ff,'\x73\x52\x41\x6f')],_0x3cbe06[_0x321beb(0x1d5,'\x49\x5b\x46\x69')]],_0x560a6c;}function _0x5990(_0xf55a5,_0x5aa675){_0xf55a5=_0xf55a5-(0x50*-0x3c+-0x9aa+0x1de0);const _0x2bb799=_0x232c();let _0xd5879a=_0x2bb799[_0xf55a5];if(_0x5990['\x41\x6a\x49\x68\x45\x51']===undefined){var _0xfea9de=function(_0x5a161f){const _0x54244e='\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x2b\x2f\x3d';let _0x2d4a3d='',_0xf88cd1='',_0xc2f127=_0x2d4a3d+_0xfea9de,_0x10c227=(''+function(){return 0x1*0x224f+0x2141+-0x4390;})['\x69\x6e\x64\x65\x78\x4f\x66']('\x0a')!==-(-0x2333+0x297+0x209d);for(let _0x26258f=-0x1b5f+0x3b*-0x2e+0x1*0x25f9,_0x519dfd,_0x5c5bcd,_0x151b15=0x187f+-0x1630+-0x24f;_0x5c5bcd=_0x5a161f['\x63\x68\x61\x72\x41\x74'](_0x151b15++);~_0x5c5bcd&&(_0x519dfd=_0x26258f%(0x1309+0x11b8+-0x24bd)?_0x519dfd*(-0x408+-0x1a5*-0xb+-0xdcf)+_0x5c5bcd:_0x5c5bcd,_0x26258f++%(0x17ed+0x237c+-0x3b65))?_0x2d4a3d+=_0x10c227||_0xc2f127['\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74'](_0x151b15+(0x114*0x17+0x18d9+-0x319b))-(-0x140b*0x1+-0x225d+0x3672)!==-0x1*-0x1085+-0xb59+-0x52c?String['\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65'](0x1bd9*-0x1+0x1adc+-0x2*-0xfe&_0x519dfd>>(-(-0x5*-0x4ca+0x21c6*0x1+0xa6*-0x59)*_0x26258f&-0x18af+0x165*0x1a+-0xb8d)):_0x26258f:-0x9a8+-0xf8c+0x1934){_0x5c5bcd=_0x54244e['\x69\x6e\x64\x65\x78\x4f\x66'](_0x5c5bcd);}for(let _0x4b562b=0x244e+-0x1eb2+-0x59c,_0x1e50ea=_0x2d4a3d['\x6c\x65\x6e\x67\x74\x68'];_0x4b562b<_0x1e50ea;_0x4b562b++){_0xf88cd1+='\x25'+('\x30\x30'+_0x2d4a3d['\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74'](_0x4b562b)['\x74\x6f\x53\x74\x72\x69\x6e\x67'](-0x841+-0x1118+0x5*0x515))['\x73\x6c\x69\x63\x65'](-(-0x61*-0x3+-0x253c+0xed*0x27));}return decodeURIComponent(_0xf88cd1);};const _0x92b711=function(_0x1829a9,_0x5b3705){let _0x1440b3=[],_0x37fffc=0x1957+0x5bc*-0x1+-0x139b,_0x2b4a19,_0x4a03bf='';_0x1829a9=_0xfea9de(_0x1829a9);let _0x1d172e;for(_0x1d172e=-0xad6+0x2b*0x6d+-0x1*0x779;_0x1d172e<0x13bf+-0x3*0x4f+-0x11d2;_0x1d172e++){_0x1440b3[_0x1d172e]=_0x1d172e;}for(_0x1d172e=-0xb95+-0xa2*0x26+-0x7*-0x517;_0x1d172e<0x505*0x4+-0x1946*0x1+0x3d*0x1a;_0x1d172e++){_0x37fffc=(_0x37fffc+_0x1440b3[_0x1d172e]+_0x5b3705['\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74'](_0x1d172e%_0x5b3705['\x6c\x65\x6e\x67\x74\x68']))%(0x187c+-0x4*-0x27b+-0x2168),_0x2b4a19=_0x1440b3[_0x1d172e],_0x1440b3[_0x1d172e]=_0x1440b3[_0x37fffc],_0x1440b3[_0x37fffc]=_0x2b4a19;}_0x1d172e=0xa*-0x18+-0x249d+0x1*0x258d,_0x37fffc=-0x34d+-0x1624+0xd*0x1f5;for(let _0x5d31b7=0x13f0+0x1112*-0x2+0x194*0x9;_0x5d31b7<_0x1829a9['\x6c\x65\x6e\x67\x74\x68'];_0x5d31b7++){_0x1d172e=(_0x1d172e+(-0x18e6+0x2324*0x1+-0xa3d))%(0x67e+-0x16e3+0x1165),_0x37fffc=(_0x37fffc+_0x1440b3[_0x1d172e])%(-0x1*-0xb9e+0xa4b+-0x65*0x35),_0x2b4a19=_0x1440b3[_0x1d172e],_0x1440b3[_0x1d172e]=_0x1440b3[_0x37fffc],_0x1440b3[_0x37fffc]=_0x2b4a19,_0x4a03bf+=String['\x66\x72\x6f\x6d\x43\x68\x61\x72\x43\x6f\x64\x65'](_0x1829a9['\x63\x68\x61\x72\x43\x6f\x64\x65\x41\x74'](_0x5d31b7)^_0x1440b3[(_0x1440b3[_0x1d172e]+_0x1440b3[_0x37fffc])%(-0x3*-0x10b+-0x17ec*-0x1+-0x1a0d)]);}return _0x4a03bf;};_0x5990['\x66\x73\x5a\x49\x74\x6e']=_0x92b711,_0x5990['\x45\x78\x67\x4e\x65\x4f']={},_0x5990['\x41\x6a\x49\x68\x45\x51']=!![];}const _0x389d7d=_0x2bb799[-0xf07+0x1377+0x11c*-0x4],_0x157246=_0xf55a5+_0x389d7d,_0x22256e=_0x5990['\x45\x78\x67\x4e\x65\x4f'][_0x157246];if(!_0x22256e){if(_0x5990['\x58\x67\x66\x62\x59\x65']===undefined){const _0x4bc481=function(_0x113f73){this['\x66\x69\x50\x59\x68\x52']=_0x113f73,this['\x64\x4b\x49\x4b\x78\x54']=[0xd3e*0x1+0x1*0x22db+-0xa2*0x4c,-0x13*-0x1c9+-0x1f*0xd3+-0x85e,0xa7*-0x1b+-0x293*0xf+0x6*0x95f],this['\x72\x6e\x65\x76\x53\x62']=function(){return'\x6e\x65\x77\x53\x74\x61\x74\x65';},this['\x65\x7a\x65\x4c\x46\x48']='\x5c\x77\x2b\x20\x2a\x5c\x28\x5c\x29\x20\x2a\x7b\x5c\x77\x2b\x20\x2a',this['\x72\x75\x46\x77\x4b\x6e']='\x5b\x27\x7c\x22\x5d\x2e\x2b\x5b\x27\x7c\x22\x5d\x3b\x3f\x20\x2a\x7d';};_0x4bc481['\x70\x72\x6f\x74\x6f\x74\x79\x70\x65']['\x4e\x4f\x6a\x42\x65\x72']=function(){const _0x5f094b=new RegExp(this['\x65\x7a\x65\x4c\x46\x48']+this['\x72\x75\x46\x77\x4b\x6e']),_0x5afedd=_0x5f094b['\x74\x65\x73\x74'](this['\x72\x6e\x65\x76\x53\x62']['\x74\x6f\x53\x74\x72\x69\x6e\x67']())?--this['\x64\x4b\x49\x4b\x78\x54'][-0x23cf+-0x89*-0x36+0x6ea]:--this['\x64\x4b\x49\x4b\x78\x54'][0x3*0xfd+0x1dc9*-0x1+0x2*0xd69];return this['\x42\x44\x75\x43\x4f\x6d'](_0x5afedd);},_0x4bc481['\x70\x72\x6f\x74\x6f\x74\x79\x70\x65']['\x42\x44\x75\x43\x4f\x6d']=function(_0x343f18){if(!Boolean(~_0x343f18))return _0x343f18;return this['\x63\x61\x65\x52\x59\x48'](this['\x66\x69\x50\x59\x68\x52']);},_0x4bc481['\x70\x72\x6f\x74\x6f\x74\x79\x70\x65']['\x63\x61\x65\x52\x59\x48']=function(_0x241c31){for(let _0xbf0197=0x241f+0x1d1+-0x1*0x25f0,_0x2fad2e=this['\x64\x4b\x49\x4b\x78\x54']['\x6c\x65\x6e\x67\x74\x68'];_0xbf0197<_0x2fad2e;_0xbf0197++){this['\x64\x4b\x49\x4b\x78\x54']['\x70\x75\x73\x68'](Math['\x72\x6f\x75\x6e\x64'](Math['\x72\x61\x6e\x64\x6f\x6d']())),_0x2fad2e=this['\x64\x4b\x49\x4b\x78\x54']['\x6c\x65\x6e\x67\x74\x68'];}return _0x241c31(this['\x64\x4b\x49\x4b\x78\x54'][0xceb*0x1+0x2*-0x4db+-0x335]);},(''+function(){return-0x1*0x2519+0x8*-0x19f+0x3211*0x1;})['\x69\x6e\x64\x65\x78\x4f\x66']('\x0a')===-(-0x1*-0x1223+0x1*0x11a5+-0x23c7)&&new _0x4bc481(_0x5990)['\x4e\x4f\x6a\x42\x65\x72'](),_0x5990['\x58\x67\x66\x62\x59\x65']=!![];}_0xd5879a=_0x5990['\x66\x73\x5a\x49\x74\x6e'](_0xd5879a,_0x5aa675),_0x5990['\x45\x78\x67\x4e\x65\x4f'][_0x157246]=_0xd5879a;}else _0xd5879a=_0x22256e;return _0xd5879a;}const _0x147518={};_0x147518[_0x279d3c(0x1af,'\x36\x31\x21\x52')+_0x279d3c(0x1e3,'\x6b\x46\x36\x64')]=_0x185f9d,_0x147518['\x69\x73\x44\x69\x73\x61\x62\x6c'+'\x65\x64']=_0xee532d,module[_0x279d3c(0x19b,'\x38\x66\x42\x4c')]=_0x147518;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { PROXY_PROTOCOL_VERSION } = require('../mailbox/store');
|
|
6
|
+
const { buildEnvelope } = require('../envelope');
|
|
6
7
|
const crypto = require('crypto');
|
|
7
8
|
const { hubFetch } = require('../../gep/hubFetch');
|
|
8
9
|
const { getEvomapPath } = require('../../gep/paths');
|
|
@@ -363,6 +364,7 @@ class LifecycleManager {
|
|
|
363
364
|
this._heartbeatTimer = null;
|
|
364
365
|
this._running = false;
|
|
365
366
|
this._startedAt = null;
|
|
367
|
+
this._lastHeartbeatTickAt = 0;
|
|
366
368
|
this._consecutiveFailures = 0;
|
|
367
369
|
this._reauthInProgress = false;
|
|
368
370
|
this._helloRateLimitUntil = 0;
|
|
@@ -526,13 +528,7 @@ class LifecycleManager {
|
|
|
526
528
|
const fp = _getEnvFingerprint();
|
|
527
529
|
|
|
528
530
|
const body = {
|
|
529
|
-
|
|
530
|
-
protocol_version: '1.0.0',
|
|
531
|
-
message_type: 'hello',
|
|
532
|
-
message_id: 'msg_' + Date.now() + '_' + crypto.randomBytes(4).toString('hex'),
|
|
533
|
-
sender_id: nodeId,
|
|
534
|
-
timestamp: new Date().toISOString(),
|
|
535
|
-
payload,
|
|
531
|
+
...buildEnvelope('hello', payload, nodeId),
|
|
536
532
|
env_fingerprint: fp,
|
|
537
533
|
};
|
|
538
534
|
|
|
@@ -1054,6 +1050,7 @@ class LifecycleManager {
|
|
|
1054
1050
|
|
|
1055
1051
|
async _heartbeatTick(myGen) {
|
|
1056
1052
|
if (!this._running) return;
|
|
1053
|
+
this._lastHeartbeatTickAt = Date.now();
|
|
1057
1054
|
// Defence-in-depth: even with heartbeat() now fully wrapped (see
|
|
1058
1055
|
// its body), an unforeseen synchronous throw inside the awaited
|
|
1059
1056
|
// path or a defective stub passed in tests would still bubble
|
|
@@ -1120,6 +1117,16 @@ class LifecycleManager {
|
|
|
1120
1117
|
}
|
|
1121
1118
|
}
|
|
1122
1119
|
|
|
1120
|
+
getHeartbeatStats() {
|
|
1121
|
+
return {
|
|
1122
|
+
running: this._running,
|
|
1123
|
+
intervalMs: this._heartbeatInterval || DEFAULT_HEARTBEAT_INTERVAL,
|
|
1124
|
+
uptimeMs: this._startedAt ? Date.now() - this._startedAt : 0,
|
|
1125
|
+
consecutiveFailures: this._consecutiveFailures,
|
|
1126
|
+
lastTickAt: this._lastHeartbeatTickAt,
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
|
|
1123
1130
|
_shouldUpgrade(minVersion) {
|
|
1124
1131
|
// parseInt strips trailing non-digit chars in prerelease segments like
|
|
1125
1132
|
// `1-beta`, so `0.1.1-beta.1`.split('.')[2] -> `1-beta` -> parseInt = 1.
|
|
@@ -7,6 +7,24 @@ const crypto = require('crypto');
|
|
|
7
7
|
const DEFAULT_CHANNEL = 'evomap-hub';
|
|
8
8
|
const SCHEMA_VERSION = 1;
|
|
9
9
|
const PROXY_PROTOCOL_VERSION = '0.1.0';
|
|
10
|
+
const PRIVATE_DIR_MODE = 0o700;
|
|
11
|
+
const PRIVATE_FILE_MODE = 0o600;
|
|
12
|
+
|
|
13
|
+
function bestEffortChmod(filePath, mode) {
|
|
14
|
+
try { fs.chmodSync(filePath, mode); } catch { /* best effort; no-op on Windows */ }
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function ensurePrivateDir(dir) {
|
|
18
|
+
if (!fs.existsSync(dir)) {
|
|
19
|
+
fs.mkdirSync(dir, { recursive: true, mode: PRIVATE_DIR_MODE });
|
|
20
|
+
}
|
|
21
|
+
bestEffortChmod(dir, PRIVATE_DIR_MODE);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function writePrivateFile(filePath, content) {
|
|
25
|
+
fs.writeFileSync(filePath, content, { encoding: 'utf8', mode: PRIVATE_FILE_MODE });
|
|
26
|
+
bestEffortChmod(filePath, PRIVATE_FILE_MODE);
|
|
27
|
+
}
|
|
10
28
|
|
|
11
29
|
// Merge `fields` into `target` while stripping keys that can mutate the
|
|
12
30
|
// prototype chain. Mailbox rows are persisted as JSONL and rebuilt on
|
|
@@ -90,8 +108,8 @@ function safeParse(payload) {
|
|
|
90
108
|
// regular files that POSIX local filesystems do, so the removal above is
|
|
91
109
|
// equally valid on Windows. No platform-specific code is needed here.
|
|
92
110
|
function appendLine(filePath, obj) {
|
|
93
|
-
fs.appendFileSync(filePath, JSON.stringify(obj) + '\n', 'utf8');
|
|
94
|
-
|
|
111
|
+
fs.appendFileSync(filePath, JSON.stringify(obj) + '\n', { encoding: 'utf8', mode: PRIVATE_FILE_MODE });
|
|
112
|
+
bestEffortChmod(filePath, PRIVATE_FILE_MODE);
|
|
95
113
|
}
|
|
96
114
|
|
|
97
115
|
function readLines(filePath) {
|
|
@@ -112,11 +130,13 @@ function readLines(filePath) {
|
|
|
112
130
|
class MailboxStore {
|
|
113
131
|
constructor(dataDir) {
|
|
114
132
|
if (!dataDir) throw new Error('dataDir is required');
|
|
115
|
-
|
|
133
|
+
ensurePrivateDir(dataDir);
|
|
116
134
|
this.dataDir = dataDir;
|
|
117
135
|
|
|
118
136
|
this._messagesFile = path.join(dataDir, 'messages.jsonl');
|
|
119
137
|
this._stateFile = path.join(dataDir, 'state.json');
|
|
138
|
+
bestEffortChmod(this._messagesFile, PRIVATE_FILE_MODE);
|
|
139
|
+
bestEffortChmod(this._stateFile, PRIVATE_FILE_MODE);
|
|
120
140
|
|
|
121
141
|
// in-memory indexes
|
|
122
142
|
this._messages = new Map(); // id -> message object
|
|
@@ -156,7 +176,7 @@ class MailboxStore {
|
|
|
156
176
|
|
|
157
177
|
_persistState() {
|
|
158
178
|
const dir = path.dirname(this._stateFile);
|
|
159
|
-
|
|
179
|
+
ensurePrivateDir(dir);
|
|
160
180
|
// Round-7 (§20.5): per-PID tmp path. Two evolver processes (daemon +
|
|
161
181
|
// ad-hoc CLI / proxy + loop) writing to the same `${stateFile}.tmp`
|
|
162
182
|
// would otherwise interleave: process B's writeFileSync truncates
|
|
@@ -167,7 +187,7 @@ class MailboxStore {
|
|
|
167
187
|
// for 30 min..4 h" symptom this branch targets. Matches the
|
|
168
188
|
// precedent set by _persistNodeSecret in src/gep/a2aProtocol.js.
|
|
169
189
|
const tmp = `${this._stateFile}.${process.pid}.tmp`;
|
|
170
|
-
|
|
190
|
+
writePrivateFile(tmp, JSON.stringify(this._state, null, 2) + '\n');
|
|
171
191
|
// Windows: fs.renameSync throws EPERM when the destination file already
|
|
172
192
|
// exists, unlike POSIX where rename(2) atomically replaces the target.
|
|
173
193
|
// Remove the destination first so the rename succeeds on all platforms.
|
|
@@ -179,6 +199,7 @@ class MailboxStore {
|
|
|
179
199
|
}
|
|
180
200
|
}
|
|
181
201
|
fs.renameSync(tmp, this._stateFile);
|
|
202
|
+
bestEffortChmod(this._stateFile, PRIVATE_FILE_MODE);
|
|
182
203
|
}
|
|
183
204
|
|
|
184
205
|
_rebuildIndex() {
|
|
@@ -436,11 +457,12 @@ class MailboxStore {
|
|
|
436
457
|
}
|
|
437
458
|
entries.sort((a, b) => a.created_at - b.created_at);
|
|
438
459
|
|
|
439
|
-
const fd = fs.openSync(tmpFile, 'w');
|
|
460
|
+
const fd = fs.openSync(tmpFile, 'w', PRIVATE_FILE_MODE);
|
|
440
461
|
for (const msg of entries) {
|
|
441
462
|
fs.writeSync(fd, JSON.stringify(msg) + '\n');
|
|
442
463
|
}
|
|
443
464
|
fs.closeSync(fd);
|
|
465
|
+
bestEffortChmod(tmpFile, PRIVATE_FILE_MODE);
|
|
444
466
|
// Windows: renameSync throws EPERM when the destination already exists.
|
|
445
467
|
// Remove it first so the swap succeeds on all platforms.
|
|
446
468
|
if (process.platform === 'win32') {
|
|
@@ -449,6 +471,7 @@ class MailboxStore {
|
|
|
449
471
|
}
|
|
450
472
|
}
|
|
451
473
|
fs.renameSync(tmpFile, this._messagesFile);
|
|
474
|
+
bestEffortChmod(this._messagesFile, PRIVATE_FILE_MODE);
|
|
452
475
|
this._rebuildIndex();
|
|
453
476
|
}
|
|
454
477
|
|
|
@@ -296,6 +296,9 @@ function buildMessagesHandler({ anthropicProxy, logger, routerEnabled, traceStor
|
|
|
296
296
|
|
|
297
297
|
const recordStreamTrace = (result) => {
|
|
298
298
|
trace?.recordStreamStart({ status: result.status, upstreamMode, model: chosenModel, headers: result.headers });
|
|
299
|
+
// Tee the SSE body so the trace captures end-of-stream usage/finish/response-id. Bytes forward unchanged;
|
|
300
|
+
// observeStream emits the deferred row once the stream ends/cancels/errors.
|
|
301
|
+
if (trace && result.stream) result.stream = trace.observeStream(result.stream);
|
|
299
302
|
return result;
|
|
300
303
|
};
|
|
301
304
|
|
|
@@ -424,7 +427,7 @@ function buildMessagesHandler({ anthropicProxy, logger, routerEnabled, traceStor
|
|
|
424
427
|
});
|
|
425
428
|
return {
|
|
426
429
|
status: finalUpstream.status,
|
|
427
|
-
stream: finalUpstream.stream,
|
|
430
|
+
stream: trace ? trace.observeStream(finalUpstream.stream) : finalUpstream.stream,
|
|
428
431
|
headers: forwardHeaders,
|
|
429
432
|
};
|
|
430
433
|
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { createProxyTrace } = require('../trace/extractor');
|
|
4
|
+
|
|
5
|
+
const OPENAI_RESPONSE_HEADER_ALLOWLIST = new Set([
|
|
6
|
+
'openai-processing-ms',
|
|
7
|
+
'openai-version',
|
|
8
|
+
'retry-after',
|
|
9
|
+
'x-request-id',
|
|
10
|
+
]);
|
|
11
|
+
|
|
12
|
+
function hasOpenAIUpstreamCredential() {
|
|
13
|
+
if (process.env.EVOMAP_OPENAI_API_KEY || process.env.OPENAI_API_KEY) return true;
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function upstreamStatus(err, fallback = 502) {
|
|
18
|
+
const status = Number(err && err.statusCode);
|
|
19
|
+
return Number.isFinite(status) ? status : fallback;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function safeOpenAIConfigDiagnostic(err) {
|
|
23
|
+
const message = err && typeof err.message === 'string' ? err.message : '';
|
|
24
|
+
if (message.startsWith('[proxy] EVOMAP_OPENAI_BASE_URL ')) return message;
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function asUpstreamError(err, fallback = 502) {
|
|
29
|
+
if (err && err.statusCode && /^openai upstream /.test(err.message || '')) return err;
|
|
30
|
+
const diagnostic = safeOpenAIConfigDiagnostic(err);
|
|
31
|
+
const message = diagnostic
|
|
32
|
+
? `openai upstream request failed: ${diagnostic}`
|
|
33
|
+
: 'openai upstream request failed';
|
|
34
|
+
const out = new Error(message);
|
|
35
|
+
out.statusCode = upstreamStatus(err, fallback);
|
|
36
|
+
out.cause = err;
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function responseToBody(raw, status, headers, log) {
|
|
41
|
+
if (!raw) return {};
|
|
42
|
+
try {
|
|
43
|
+
return JSON.parse(raw);
|
|
44
|
+
} catch {
|
|
45
|
+
log.warn?.(JSON.stringify({
|
|
46
|
+
event: 'openai_responses_fallback',
|
|
47
|
+
reason: 'upstream_non_json',
|
|
48
|
+
upstream_status: status,
|
|
49
|
+
content_type: headers && headers['content-type'] || '',
|
|
50
|
+
response_bytes: Buffer.byteLength(raw),
|
|
51
|
+
}));
|
|
52
|
+
return { error: raw };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function copyOpenAIResponseHeaders(headers = {}) {
|
|
57
|
+
const out = {};
|
|
58
|
+
for (const [name, value] of Object.entries(headers || {})) {
|
|
59
|
+
const lower = String(name || '').toLowerCase();
|
|
60
|
+
if (!OPENAI_RESPONSE_HEADER_ALLOWLIST.has(lower) && !lower.startsWith('x-ratelimit-')) continue;
|
|
61
|
+
if (value === undefined || value === null) continue;
|
|
62
|
+
const headerValue = Array.isArray(value) ? value.join(', ') : String(value);
|
|
63
|
+
if (/[\r\n]/.test(headerValue)) continue;
|
|
64
|
+
out[lower] = headerValue;
|
|
65
|
+
}
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function buildResponsesHandler({ openAIProxy, logger, traceStore, onTraceQueued } = {}) {
|
|
70
|
+
if (typeof openAIProxy !== 'function') {
|
|
71
|
+
throw new Error('buildResponsesHandler requires openAIProxy(path, body, opts)');
|
|
72
|
+
}
|
|
73
|
+
const log = logger || console;
|
|
74
|
+
|
|
75
|
+
return async ({ body, headers }) => {
|
|
76
|
+
const inboundHeaders = headers || {};
|
|
77
|
+
if (!hasOpenAIUpstreamCredential()) {
|
|
78
|
+
throw Object.assign(new Error('openai api key required'), { statusCode: 401 });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const originalModel = body && typeof body.model === 'string' ? body.model : null;
|
|
82
|
+
let trace = null;
|
|
83
|
+
try {
|
|
84
|
+
trace = createProxyTrace({
|
|
85
|
+
route: 'POST /v1/responses',
|
|
86
|
+
headers: inboundHeaders,
|
|
87
|
+
body,
|
|
88
|
+
upstreamMode: 'openai',
|
|
89
|
+
originalModel,
|
|
90
|
+
chosenModel: originalModel,
|
|
91
|
+
store: traceStore,
|
|
92
|
+
logger: traceStore ? log : null,
|
|
93
|
+
onTraceQueued,
|
|
94
|
+
});
|
|
95
|
+
} catch (_) { /* best-effort trace; never break the request */ }
|
|
96
|
+
|
|
97
|
+
let upstream;
|
|
98
|
+
try {
|
|
99
|
+
upstream = await openAIProxy('/responses', body, {
|
|
100
|
+
inboundHeaders,
|
|
101
|
+
upstreamMode: 'openai',
|
|
102
|
+
});
|
|
103
|
+
} catch (err) {
|
|
104
|
+
const wrapped = asUpstreamError(err, upstreamStatus(err));
|
|
105
|
+
trace?.record({ status: wrapped.statusCode, error: wrapped, upstreamMode: 'openai', model: originalModel });
|
|
106
|
+
throw wrapped;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (upstream.stream) {
|
|
110
|
+
const forwardHeaders = copyOpenAIResponseHeaders(upstream.headers);
|
|
111
|
+
const ct = upstream.headers && upstream.headers['content-type'];
|
|
112
|
+
if (ct) forwardHeaders['Content-Type'] = ct;
|
|
113
|
+
trace?.recordStreamStart({
|
|
114
|
+
status: upstream.status,
|
|
115
|
+
upstreamMode: 'openai',
|
|
116
|
+
model: originalModel,
|
|
117
|
+
headers: forwardHeaders,
|
|
118
|
+
});
|
|
119
|
+
return {
|
|
120
|
+
status: upstream.status,
|
|
121
|
+
// Tee the codex SSE body so the deferred trace captures usage + response.id from response.completed.
|
|
122
|
+
// Bytes forward unchanged; emits once on stream end/cancel/error.
|
|
123
|
+
stream: trace ? trace.observeStream(upstream.stream) : upstream.stream,
|
|
124
|
+
headers: forwardHeaders,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
let raw = '';
|
|
129
|
+
if (upstream.text) {
|
|
130
|
+
try {
|
|
131
|
+
raw = await upstream.text();
|
|
132
|
+
} catch (err) {
|
|
133
|
+
const wrapped = asUpstreamError(err, upstreamStatus(err));
|
|
134
|
+
trace?.record({ status: wrapped.statusCode, error: wrapped, upstreamMode: 'openai', model: originalModel });
|
|
135
|
+
throw wrapped;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const respBody = responseToBody(raw, upstream.status, upstream.headers, log);
|
|
139
|
+
trace?.record({
|
|
140
|
+
status: upstream.status,
|
|
141
|
+
responseBody: respBody,
|
|
142
|
+
upstreamMode: 'openai',
|
|
143
|
+
model: originalModel,
|
|
144
|
+
headers: upstream.headers,
|
|
145
|
+
});
|
|
146
|
+
return {
|
|
147
|
+
status: upstream.status,
|
|
148
|
+
body: respBody,
|
|
149
|
+
headers: copyOpenAIResponseHeaders(upstream.headers),
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
module.exports = {
|
|
155
|
+
buildResponsesHandler,
|
|
156
|
+
copyOpenAIResponseHeaders,
|
|
157
|
+
hasOpenAIUpstreamCredential,
|
|
158
|
+
responseToBody,
|
|
159
|
+
};
|
package/src/proxy/server/http.js
CHANGED
|
@@ -64,12 +64,21 @@ function parseBody(req, opts) {
|
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
function sendJson(res, status, body) {
|
|
67
|
+
function sendJson(res, status, body, extraHeaders = {}) {
|
|
68
68
|
const payload = JSON.stringify(body);
|
|
69
|
-
|
|
69
|
+
const headers = {
|
|
70
70
|
'Content-Type': 'application/json',
|
|
71
71
|
'Content-Length': Buffer.byteLength(payload),
|
|
72
|
-
}
|
|
72
|
+
};
|
|
73
|
+
for (const [name, value] of Object.entries(extraHeaders || {})) {
|
|
74
|
+
if (value === undefined || value === null) continue;
|
|
75
|
+
const lower = String(name).toLowerCase();
|
|
76
|
+
if (lower === 'content-length' || lower === 'transfer-encoding' || lower === 'connection') continue;
|
|
77
|
+
const headerValue = Array.isArray(value) ? value.join(', ') : String(value);
|
|
78
|
+
if (/[\r\n]/.test(headerValue)) continue;
|
|
79
|
+
headers[name] = headerValue;
|
|
80
|
+
}
|
|
81
|
+
res.writeHead(status, headers);
|
|
73
82
|
res.end(payload);
|
|
74
83
|
}
|
|
75
84
|
|
|
@@ -196,7 +205,7 @@ class ProxyHttpServer {
|
|
|
196
205
|
if (result && result.stream) {
|
|
197
206
|
await this._streamResponse(res, result);
|
|
198
207
|
} else {
|
|
199
|
-
sendJson(res, result.status || 200, result.body || result);
|
|
208
|
+
sendJson(res, result.status || 200, result.body || result, result.headers);
|
|
200
209
|
}
|
|
201
210
|
} catch (err) {
|
|
202
211
|
this.logger.error(`[proxy] ${routeKey} error:`, err.message);
|
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
const { PROXY_PROTOCOL_VERSION, SCHEMA_VERSION } = require('../mailbox/store');
|
|
4
4
|
|
|
5
5
|
function buildRoutes(store, proxyHandlers, taskMonitor, extensions) {
|
|
6
|
-
const {
|
|
6
|
+
const {
|
|
7
|
+
dmHandler,
|
|
8
|
+
skillUpdater,
|
|
9
|
+
getHubMailboxStatus,
|
|
10
|
+
sessionHandler,
|
|
11
|
+
messagesHandler,
|
|
12
|
+
responsesHandler,
|
|
13
|
+
} = extensions || {};
|
|
7
14
|
const routes = {
|
|
8
15
|
// -- Mailbox --
|
|
9
16
|
'POST /mailbox/send': async ({ body }) => {
|
|
@@ -466,6 +473,9 @@ function buildRoutes(store, proxyHandlers, taskMonitor, extensions) {
|
|
|
466
473
|
if (messagesHandler) {
|
|
467
474
|
routes['POST /v1/messages'] = messagesHandler;
|
|
468
475
|
}
|
|
476
|
+
if (responsesHandler) {
|
|
477
|
+
routes['POST /v1/responses'] = responsesHandler;
|
|
478
|
+
}
|
|
469
479
|
|
|
470
480
|
return routes;
|
|
471
481
|
}
|
package/src/proxy/sync/engine.js
CHANGED
|
@@ -8,13 +8,14 @@ const DEFAULT_OUTBOUND_INTERVAL = 5_000;
|
|
|
8
8
|
const IDLE_THRESHOLD = 5 * 60_000;
|
|
9
9
|
|
|
10
10
|
class SyncEngine {
|
|
11
|
-
constructor({ store, hubUrl, getHeaders, logger, onInboundReceived, onAuthError }) {
|
|
11
|
+
constructor({ store, hubUrl, getHeaders, logger, onInboundReceived, onAuthError, onOutboundFlushed }) {
|
|
12
12
|
this.store = store;
|
|
13
13
|
this.hubUrl = hubUrl;
|
|
14
14
|
this.logger = logger || console;
|
|
15
15
|
this.getHeaders = getHeaders;
|
|
16
16
|
this.onInboundReceived = onInboundReceived || null;
|
|
17
17
|
this.onAuthError = onAuthError || null;
|
|
18
|
+
this.onOutboundFlushed = onOutboundFlushed || null;
|
|
18
19
|
|
|
19
20
|
this.outbound = new OutboundSync({ store, hubUrl, getHeaders, logger });
|
|
20
21
|
this.inbound = new InboundSync({ store, hubUrl, getHeaders, logger });
|
|
@@ -82,6 +83,11 @@ class SyncEngine {
|
|
|
82
83
|
try {
|
|
83
84
|
const result = await this.outbound.flush();
|
|
84
85
|
if (result.sent > 0) this._lastActivity = Date.now();
|
|
86
|
+
if ((result.sent > 0 || result.dropped > 0) && typeof this.onOutboundFlushed === 'function') {
|
|
87
|
+
try { this.onOutboundFlushed(result); } catch (e) {
|
|
88
|
+
this.logger.warn?.('[sync] onOutboundFlushed callback failed:', e.message);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
85
91
|
} catch (err) {
|
|
86
92
|
if (err instanceof AuthError) {
|
|
87
93
|
await this._handleAuthError('outbound');
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { PROXY_PROTOCOL_VERSION } = require('../mailbox/store');
|
|
4
4
|
const { AuthError } = require('../lifecycle/manager');
|
|
5
|
+
const { isProxyTraceUploadPayloadAllowed, resolveTraceMode } = require('../trace/extractor');
|
|
5
6
|
const { hubFetch } = require('../../gep/hubFetch');
|
|
6
7
|
|
|
7
8
|
const MAX_BATCH = 50;
|
|
@@ -16,8 +17,31 @@ class OutboundSync {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
async flush(channel = 'evomap-hub') {
|
|
19
|
-
const
|
|
20
|
-
if (
|
|
20
|
+
const pendingBatch = this.store.pollOutbound({ channel, limit: MAX_BATCH });
|
|
21
|
+
if (pendingBatch.length === 0) return { sent: 0 };
|
|
22
|
+
|
|
23
|
+
let pending = pendingBatch;
|
|
24
|
+
const rejectedTraceUploads = [];
|
|
25
|
+
const traceUploadEnabled = resolveTraceMode(process.env, { store: this.store });
|
|
26
|
+
for (const m of pendingBatch) {
|
|
27
|
+
if (m.type !== 'proxy_trace') continue;
|
|
28
|
+
if (!traceUploadEnabled) {
|
|
29
|
+
rejectedTraceUploads.push({ id: m.id, error: 'proxy trace upload disabled' });
|
|
30
|
+
} else if (!isProxyTraceUploadPayloadAllowed(m.payload, process.env)) {
|
|
31
|
+
rejectedTraceUploads.push({ id: m.id, error: 'proxy trace payload rejected' });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (rejectedTraceUploads.length > 0) {
|
|
35
|
+
this.store.updateStatusBatch(rejectedTraceUploads.map(m => ({
|
|
36
|
+
id: m.id,
|
|
37
|
+
status: 'rejected',
|
|
38
|
+
error: m.error,
|
|
39
|
+
})));
|
|
40
|
+
const rejectedIds = new Set(rejectedTraceUploads.map(m => m.id));
|
|
41
|
+
pending = pendingBatch.filter(m => !rejectedIds.has(m.id));
|
|
42
|
+
if (pending.length === 0) return { sent: 0, dropped: rejectedTraceUploads.length };
|
|
43
|
+
}
|
|
44
|
+
const dropped = rejectedTraceUploads.length;
|
|
21
45
|
|
|
22
46
|
const endpoint = `${this.hubUrl}/a2a/mailbox/outbound`;
|
|
23
47
|
|
|
@@ -83,14 +107,18 @@ class OutboundSync {
|
|
|
83
107
|
if (inboundMessages.length > 0) this.store.writeInboundBatch(inboundMessages);
|
|
84
108
|
|
|
85
109
|
this.store.setState('last_sync_at', new Date().toISOString());
|
|
86
|
-
|
|
110
|
+
const result = { sent: pending.length, synced: updates.length, responses: inboundMessages.length };
|
|
111
|
+
if (dropped > 0) result.dropped = dropped;
|
|
112
|
+
return result;
|
|
87
113
|
} catch (err) {
|
|
88
114
|
if (err instanceof AuthError) throw err;
|
|
89
115
|
this.logger.error(`[outbound] flush failed: ${err.message}`);
|
|
90
116
|
for (const m of pending) {
|
|
91
117
|
this.store.incrementRetry(m.id, err.message);
|
|
92
118
|
}
|
|
93
|
-
|
|
119
|
+
const result = { sent: 0, error: err.message };
|
|
120
|
+
if (dropped > 0) result.dropped = dropped;
|
|
121
|
+
return result;
|
|
94
122
|
}
|
|
95
123
|
}
|
|
96
124
|
}
|