@evomap/evolver 1.90.0 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -564
- package/bin/evolver-llm-proxy.js +3 -0
- package/bin/evolver-mcp.js +2 -0
- package/bin/evolver-proxy.js +3 -0
- package/bin/evolver.js +4 -0
- package/index.js +1 -3670
- package/package.json +32 -62
- package/CONTRIBUTING.md +0 -19
- package/LICENSE +0 -641
- package/README.ja-JP.md +0 -521
- package/README.ko-KR.md +0 -520
- package/README.zh-CN.md +0 -531
- package/SKILL.md +0 -365
- package/assets/cover.png +0 -0
- package/assets/gep/genes.seed.json +0 -496
- package/conformance/savings-core/constants.json +0 -30
- package/conformance/savings-core/golden-vectors.json +0 -333
- package/scripts/a2a_export.js +0 -63
- package/scripts/a2a_ingest.js +0 -79
- package/scripts/a2a_promote.js +0 -118
- package/scripts/analyze_by_skill.js +0 -121
- package/scripts/build_binaries.js +0 -479
- package/scripts/check-changelog.js +0 -166
- package/scripts/extract_log.js +0 -85
- package/scripts/generate_history.js +0 -75
- package/scripts/gep_append_event.js +0 -96
- package/scripts/gep_personality_report.js +0 -234
- package/scripts/human_report.js +0 -147
- package/scripts/recall-verify-report.js +0 -234
- package/scripts/recover_loop.js +0 -61
- package/scripts/refresh_stars_badge.js +0 -168
- package/scripts/seed-merchants.js +0 -91
- package/scripts/skill2recipes.js +0 -118
- package/scripts/suggest_version.js +0 -89
- package/scripts/validate-modules.js +0 -38
- package/scripts/validate-suite.js +0 -78
- package/src/adapters/claudeCode.js +0 -194
- package/src/adapters/codex.js +0 -216
- package/src/adapters/cursor.js +0 -91
- package/src/adapters/hookAdapter.js +0 -469
- package/src/adapters/kiro.js +0 -195
- package/src/adapters/opencode.js +0 -326
- package/src/adapters/scripts/_lockPaths.js +0 -74
- package/src/adapters/scripts/_memoryFiltering.js +0 -35
- package/src/adapters/scripts/_runtimePaths.js +0 -440
- package/src/adapters/scripts/evolver-session-end.js +0 -321
- package/src/adapters/scripts/evolver-session-start.js +0 -587
- package/src/adapters/scripts/evolver-signal-detect.js +0 -98
- package/src/adapters/scripts/evolver-task-recall.js +0 -173
- package/src/atp/atpExecute.js +0 -283
- package/src/atp/atpTaskPickup.js +0 -233
- package/src/atp/autoBuyer.js +0 -382
- package/src/atp/autoDeliver.js +0 -215
- package/src/atp/cli.js +0 -354
- package/src/atp/cliAutobuyPrompt.js +0 -154
- package/src/atp/consumerAgent.js +0 -157
- package/src/atp/defaultHandler.js +0 -69
- package/src/atp/heartbeatSignalsHandler.js +0 -254
- package/src/atp/hubClient.js +0 -317
- package/src/atp/index.js +0 -38
- package/src/atp/merchantAgent.js +0 -118
- package/src/atp/protocol.js +0 -41
- package/src/atp/questionComposer.js +0 -133
- package/src/atp/serviceHelper.js +0 -92
- package/src/canary.js +0 -13
- package/src/config.js +0 -351
- package/src/evolve/guards.js +0 -1
- package/src/evolve/pipeline/collect.js +0 -1
- package/src/evolve/pipeline/dispatch.js +0 -1
- package/src/evolve/pipeline/enrich.js +0 -1
- package/src/evolve/pipeline/hub.js +0 -1
- package/src/evolve/pipeline/select.js +0 -1
- package/src/evolve/pipeline/signals.js +0 -1
- package/src/evolve/utils.js +0 -1
- package/src/evolve.js +0 -1
- package/src/experiment/agentRunner.js +0 -229
- package/src/experiment/cli.js +0 -159
- package/src/experiment/comparison.js +0 -233
- package/src/experiment/metrics.js +0 -75
- package/src/forceUpdate.js +0 -991
- package/src/gep/a2a.js +0 -173
- package/src/gep/a2aProtocol.js +0 -1
- package/src/gep/analyzer.js +0 -35
- package/src/gep/antiAbuseTelemetry.js +0 -1
- package/src/gep/assetCallLog.js +0 -197
- package/src/gep/assetStore.js +0 -723
- package/src/gep/assets.js +0 -36
- package/src/gep/autoDistillConv.js +0 -1
- package/src/gep/autoDistillLlm.js +0 -1
- package/src/gep/bridge.js +0 -138
- package/src/gep/candidateEval.js +0 -1
- package/src/gep/candidates.js +0 -1
- package/src/gep/claimNudge.js +0 -121
- package/src/gep/cliContracts.js +0 -1190
- package/src/gep/contentHash.js +0 -1
- package/src/gep/conversationDistiller.js +0 -1
- package/src/gep/conversationSniffer.js +0 -1
- package/src/gep/crypto.js +0 -1
- package/src/gep/curriculum.js +0 -1
- package/src/gep/deviceId.js +0 -1
- package/src/gep/directoryClient.js +0 -115
- package/src/gep/envFingerprint.js +0 -1
- package/src/gep/epigenetics.js +0 -1
- package/src/gep/execBridge.js +0 -1
- package/src/gep/executionTrace.js +0 -291
- package/src/gep/explore.js +0 -1
- package/src/gep/featureFlags.js +0 -121
- package/src/gep/gitOps.js +0 -265
- package/src/gep/hash.js +0 -1
- package/src/gep/hostErrorClassifier.js +0 -34
- package/src/gep/hubFetch.js +0 -1
- package/src/gep/hubReview.js +0 -1
- package/src/gep/hubSearch.js +0 -1
- package/src/gep/hubVerify.js +0 -1
- package/src/gep/idleScheduler.js +0 -400
- package/src/gep/issueReporter.js +0 -416
- package/src/gep/learningSignals.js +0 -1
- package/src/gep/llmReview.js +0 -92
- package/src/gep/localStateAwareness.js +0 -243
- package/src/gep/mailboxTransport.js +0 -119
- package/src/gep/memoryGraph.js +0 -1
- package/src/gep/memoryGraphAdapter.js +0 -1
- package/src/gep/mutation.js +0 -1
- package/src/gep/narrativeMemory.js +0 -1
- package/src/gep/oauthLogin.js +0 -181
- package/src/gep/openPRRegistry.js +0 -1
- package/src/gep/paths.js +0 -522
- package/src/gep/personality.js +0 -1
- package/src/gep/policyCheck.js +0 -1
- package/src/gep/portable.js +0 -103
- package/src/gep/privacyClient.js +0 -235
- package/src/gep/prompt.js +0 -1
- package/src/gep/questionGenerator.js +0 -518
- package/src/gep/recallInject.js +0 -1
- package/src/gep/recallVerifier.js +0 -1
- package/src/gep/reflection.js +0 -1
- package/src/gep/sanitize.js +0 -264
- package/src/gep/savingsCore.js +0 -1
- package/src/gep/schemas/capsule.js +0 -170
- package/src/gep/schemas/gene.js +0 -154
- package/src/gep/schemas/index.js +0 -8
- package/src/gep/schemas/protocol.js +0 -51
- package/src/gep/schemas/task.js +0 -74
- package/src/gep/selector.js +0 -1
- package/src/gep/selfPR.js +0 -469
- package/src/gep/signals.js +0 -776
- package/src/gep/skill2gep.js +0 -1056
- package/src/gep/skill2gepAudit.js +0 -303
- package/src/gep/skill2recipes.js +0 -511
- package/src/gep/skillDistiller.js +0 -1
- package/src/gep/skillPublisher.js +0 -358
- package/src/gep/solidify.js +0 -1
- package/src/gep/strategy.js +0 -1
- package/src/gep/taskReceiver.js +0 -575
- package/src/gep/tokenSavings.js +0 -1
- package/src/gep/trajectoryExport.js +0 -1
- package/src/gep/validationReport.js +0 -55
- package/src/gep/validator/index.js +0 -411
- package/src/gep/validator/reporter.js +0 -210
- package/src/gep/validator/sandboxExecutor.js +0 -480
- package/src/gep/validator/stakeBootstrap.js +0 -357
- package/src/gep/workspaceKeychain.js +0 -1
- package/src/ops/cleanup.js +0 -80
- package/src/ops/commentary.js +0 -60
- package/src/ops/health_check.js +0 -104
- package/src/ops/index.js +0 -11
- package/src/ops/innovation.js +0 -67
- package/src/ops/lifecycle.js +0 -798
- package/src/ops/self_repair.js +0 -76
- package/src/ops/skills_monitor.js +0 -147
- package/src/ops/trigger.js +0 -33
- package/src/proxy/clientSettings.js +0 -405
- package/src/proxy/envelope.js +0 -59
- package/src/proxy/extensions/dmHandler.js +0 -45
- package/src/proxy/extensions/sessionHandler.js +0 -141
- package/src/proxy/extensions/skillUpdater.js +0 -64
- package/src/proxy/extensions/traceControl.js +0 -1
- package/src/proxy/index.js +0 -1395
- package/src/proxy/inject.js +0 -1
- package/src/proxy/lifecycle/manager.js +0 -1568
- package/src/proxy/mailbox/state.js +0 -207
- package/src/proxy/mailbox/store.js +0 -602
- package/src/proxy/router/cache_passthrough.js +0 -26
- package/src/proxy/router/features.js +0 -84
- package/src/proxy/router/gemini_route.js +0 -154
- package/src/proxy/router/messages_route.js +0 -535
- package/src/proxy/router/model_router.js +0 -113
- package/src/proxy/router/models_route.js +0 -52
- package/src/proxy/router/ollama_route.js +0 -103
- package/src/proxy/router/responses_route.js +0 -170
- package/src/proxy/router/vertex_route.js +0 -110
- package/src/proxy/server/http.js +0 -363
- package/src/proxy/server/routes.js +0 -558
- package/src/proxy/server/settings.js +0 -115
- package/src/proxy/sync/engine.js +0 -179
- package/src/proxy/sync/inbound.js +0 -211
- package/src/proxy/sync/outbound.js +0 -361
- package/src/proxy/task/monitor.js +0 -131
- package/src/proxy/trace/extractor.js +0 -1
- package/src/proxy/trace/usage.js +0 -1
- package/src/solo/breaker.js +0 -25
- package/src/solo/gitGuard.js +0 -65
- package/src/webui/client/clientJs/assets.js +0 -111
- package/src/webui/client/clientJs/bootstrap.js +0 -92
- package/src/webui/client/clientJs/common.js +0 -77
- package/src/webui/client/clientJs/i18n.js +0 -366
- package/src/webui/client/clientJs/index.js +0 -35
- package/src/webui/client/clientJs/interactions.js +0 -351
- package/src/webui/client/clientJs/overview.js +0 -152
- package/src/webui/client/clientJs/personality.js +0 -285
- package/src/webui/client/clientJs/pipelines.js +0 -330
- package/src/webui/client/indexHtml.js +0 -221
- package/src/webui/client/static.js +0 -23
- package/src/webui/client/stylesCss.js +0 -639
- package/src/webui/client/vendor/README.md +0 -15
- package/src/webui/client/vendor/echarts.min.js +0 -45
- package/src/webui/index.js +0 -14
- package/src/webui/observer/assets.js +0 -146
- package/src/webui/observer/index.js +0 -37
- package/src/webui/observer/interactions.js +0 -127
- package/src/webui/observer/jsonl.js +0 -75
- package/src/webui/observer/paths.js +0 -46
- package/src/webui/observer/personality.js +0 -43
- package/src/webui/observer/pipelineEvents.js +0 -58
- package/src/webui/observer/redact.js +0 -63
- package/src/webui/observer/runs.js +0 -356
- package/src/webui/observer/safety.js +0 -57
- package/src/webui/observer/skills.js +0 -70
- package/src/webui/observer/status.js +0 -71
- package/src/webui/server/http.js +0 -138
- package/src/webui/server/routes.js +0 -41
package/src/atp/cli.js
DELETED
|
@@ -1,354 +0,0 @@
|
|
|
1
|
-
// ATP CLI: lightweight argument parsers and runners for the `buy`, `orders`,
|
|
2
|
-
// and `verify` subcommands. Separated from index.js so they can be unit-tested
|
|
3
|
-
// without booting the full evolver loop.
|
|
4
|
-
//
|
|
5
|
-
// Public API:
|
|
6
|
-
// parseBuyArgs(args) -> { ok, opts?, error? }
|
|
7
|
-
// parseOrdersArgs(args)-> { ok, opts?, error? }
|
|
8
|
-
// parseVerifyArgs(args)-> { ok, opts?, error? }
|
|
9
|
-
// runBuy(opts, deps)
|
|
10
|
-
// runOrders(opts, deps)
|
|
11
|
-
// runVerify(opts, deps)
|
|
12
|
-
//
|
|
13
|
-
// `deps` is an object containing the ATP module (defaults to require('./index')),
|
|
14
|
-
// injectable for tests. Each runner returns a Promise that resolves to
|
|
15
|
-
// { exitCode: number, output?: string, data?: object }.
|
|
16
|
-
|
|
17
|
-
const {
|
|
18
|
-
ATP_VERIFY_MODES,
|
|
19
|
-
ATP_VERIFY_ACTIONS,
|
|
20
|
-
ATP_ROUTING_MODES,
|
|
21
|
-
ATP_PROOF_STATUSES,
|
|
22
|
-
ATP_ROLES,
|
|
23
|
-
} = require('./protocol');
|
|
24
|
-
|
|
25
|
-
function _parseNamed(args, longFlag, shortFlag) {
|
|
26
|
-
const long = args.findIndex(a => typeof a === 'string' && (a === longFlag || a.startsWith(longFlag + '=')));
|
|
27
|
-
if (long !== -1) {
|
|
28
|
-
const token = args[long];
|
|
29
|
-
if (token.startsWith(longFlag + '=')) return token.slice(longFlag.length + 1);
|
|
30
|
-
if (args[long + 1] && !String(args[long + 1]).startsWith('--')) return args[long + 1];
|
|
31
|
-
}
|
|
32
|
-
if (shortFlag) {
|
|
33
|
-
const short = args.indexOf(shortFlag);
|
|
34
|
-
if (short !== -1 && args[short + 1] && !String(args[short + 1]).startsWith('--')) return args[short + 1];
|
|
35
|
-
}
|
|
36
|
-
return null;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function _toBool(v) {
|
|
40
|
-
if (typeof v !== 'string') return false;
|
|
41
|
-
const s = v.toLowerCase();
|
|
42
|
-
return s === '1' || s === 'true' || s === 'yes' || s === 'on';
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function parseBuyArgs(args) {
|
|
46
|
-
if (!Array.isArray(args) || args.length === 0) {
|
|
47
|
-
return { ok: false, error: 'buy requires <capabilities>: comma-separated list (e.g. code_review,bug_fix)' };
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// First positional (not starting with --) is the capability list.
|
|
51
|
-
let capabilitiesRaw = null;
|
|
52
|
-
for (let i = 0; i < args.length; i++) {
|
|
53
|
-
const a = args[i];
|
|
54
|
-
if (typeof a === 'string' && !a.startsWith('--')) {
|
|
55
|
-
capabilitiesRaw = a;
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (!capabilitiesRaw) {
|
|
60
|
-
return { ok: false, error: 'buy requires <capabilities>: comma-separated list' };
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const capabilities = capabilitiesRaw.split(',').map(s => s.trim()).filter(Boolean);
|
|
64
|
-
if (capabilities.length === 0) {
|
|
65
|
-
return { ok: false, error: 'no valid capabilities parsed from: ' + capabilitiesRaw };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const budgetRaw = _parseNamed(args, '--budget', '-b');
|
|
69
|
-
const budget = Math.max(1, Math.round(Number(budgetRaw) || 10));
|
|
70
|
-
|
|
71
|
-
const question = _parseNamed(args, '--question', '-q') || '';
|
|
72
|
-
const routingMode = _parseNamed(args, '--routing', null) || 'fastest';
|
|
73
|
-
const verifyMode = _parseNamed(args, '--verify', null) || 'auto';
|
|
74
|
-
const noWait = args.includes('--no-wait');
|
|
75
|
-
const timeoutMsRaw = _parseNamed(args, '--timeout', null);
|
|
76
|
-
const timeoutMs = timeoutMsRaw ? Math.max(1000, Math.round(Number(timeoutMsRaw) * 1000)) : 300000;
|
|
77
|
-
|
|
78
|
-
return {
|
|
79
|
-
ok: true,
|
|
80
|
-
opts: {
|
|
81
|
-
capabilities,
|
|
82
|
-
budget,
|
|
83
|
-
question,
|
|
84
|
-
routingMode,
|
|
85
|
-
verifyMode,
|
|
86
|
-
noWait,
|
|
87
|
-
timeoutMs,
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function parseOrdersArgs(args) {
|
|
93
|
-
const role = _parseNamed(args, '--role', null);
|
|
94
|
-
if (role && !ATP_ROLES.includes(role)) {
|
|
95
|
-
return { ok: false, error: 'invalid --role: ' + role + ' (expected ' + ATP_ROLES.join('|') + ')' };
|
|
96
|
-
}
|
|
97
|
-
const status = _parseNamed(args, '--status', null);
|
|
98
|
-
if (status && !ATP_PROOF_STATUSES.includes(status)) {
|
|
99
|
-
return { ok: false, error: 'invalid --status: ' + status };
|
|
100
|
-
}
|
|
101
|
-
const limitRaw = _parseNamed(args, '--limit', null);
|
|
102
|
-
const limit = limitRaw ? Math.max(1, Math.min(100, Math.round(Number(limitRaw)))) : 20;
|
|
103
|
-
const jsonOut = args.includes('--json');
|
|
104
|
-
return {
|
|
105
|
-
ok: true,
|
|
106
|
-
opts: { role: role || 'consumer', status: status || null, limit, jsonOut },
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function parseVerifyArgs(args) {
|
|
111
|
-
let orderId = null;
|
|
112
|
-
for (let i = 0; i < args.length; i++) {
|
|
113
|
-
const a = args[i];
|
|
114
|
-
if (typeof a === 'string' && !a.startsWith('--')) {
|
|
115
|
-
orderId = a;
|
|
116
|
-
break;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
if (!orderId) {
|
|
120
|
-
return { ok: false, error: 'verify requires <orderId>' };
|
|
121
|
-
}
|
|
122
|
-
const action = _parseNamed(args, '--action', null) || 'confirm';
|
|
123
|
-
if (!ATP_VERIFY_ACTIONS.includes(action)) {
|
|
124
|
-
return { ok: false, error: 'invalid --action: ' + action + ' (expected ' + ATP_VERIFY_ACTIONS.join('|') + ')' };
|
|
125
|
-
}
|
|
126
|
-
return { ok: true, opts: { orderId, action } };
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// `evolver atp <enable|disable|status>` — manage autoBuyer consent ack file.
|
|
130
|
-
// Non-TTY users (daemon, CI, hooks) opt in here instead of the interactive
|
|
131
|
-
// first-run prompt. Returns { ok, opts: { sub } } or { ok: false, error }.
|
|
132
|
-
function parseAtpArgs(args) {
|
|
133
|
-
if (!Array.isArray(args) || args.length === 0) {
|
|
134
|
-
return { ok: false, error: 'atp requires <enable|disable|status>' };
|
|
135
|
-
}
|
|
136
|
-
let sub = null;
|
|
137
|
-
for (let i = 0; i < args.length; i++) {
|
|
138
|
-
const a = args[i];
|
|
139
|
-
if (typeof a === 'string' && !a.startsWith('--')) {
|
|
140
|
-
sub = a.toLowerCase();
|
|
141
|
-
break;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
if (!sub || !['enable', 'disable', 'status'].includes(sub)) {
|
|
145
|
-
return { ok: false, error: 'atp subcommand must be enable|disable|status (got: ' + sub + ')' };
|
|
146
|
-
}
|
|
147
|
-
return { ok: true, opts: { sub } };
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async function runBuy(opts, deps) {
|
|
151
|
-
const atp = (deps && deps.atp) || require('./index');
|
|
152
|
-
const consumerAgent = atp.consumerAgent;
|
|
153
|
-
const log = (deps && deps.log) || console.log;
|
|
154
|
-
const err = (deps && deps.err) || console.error;
|
|
155
|
-
|
|
156
|
-
log('[ATP] Placing order: capabilities=' + opts.capabilities.join(',') + ' budget=' + opts.budget + ' mode=' + opts.routingMode);
|
|
157
|
-
|
|
158
|
-
try {
|
|
159
|
-
if (opts.noWait) {
|
|
160
|
-
const result = await consumerAgent.orderService({
|
|
161
|
-
capabilities: opts.capabilities,
|
|
162
|
-
budget: opts.budget,
|
|
163
|
-
routingMode: opts.routingMode,
|
|
164
|
-
verifyMode: opts.verifyMode,
|
|
165
|
-
question: opts.question,
|
|
166
|
-
});
|
|
167
|
-
if (!result.ok) {
|
|
168
|
-
err('[ATP] Order failed: ' + (result.error || 'unknown'));
|
|
169
|
-
return { exitCode: 1, data: result };
|
|
170
|
-
}
|
|
171
|
-
log('[ATP] Order placed: ' + result.data.order_id);
|
|
172
|
-
return { exitCode: 0, data: result.data };
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const result = await consumerAgent.orderAndWait({
|
|
176
|
-
capabilities: opts.capabilities,
|
|
177
|
-
budget: opts.budget,
|
|
178
|
-
routingMode: opts.routingMode,
|
|
179
|
-
verifyMode: opts.verifyMode,
|
|
180
|
-
question: opts.question,
|
|
181
|
-
timeoutMs: opts.timeoutMs,
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
if (!result.ok) {
|
|
185
|
-
err('[ATP] Order lifecycle failed: ' + (result.error || 'unknown'));
|
|
186
|
-
return { exitCode: 1, data: result };
|
|
187
|
-
}
|
|
188
|
-
log('[ATP] Order settled: ' + (result.order && result.order.order_id));
|
|
189
|
-
if (result.finalStatus) {
|
|
190
|
-
log('[ATP] Final status: ' + JSON.stringify(result.finalStatus, null, 2));
|
|
191
|
-
}
|
|
192
|
-
return { exitCode: 0, data: result };
|
|
193
|
-
} catch (e) {
|
|
194
|
-
err('[ATP] buy error: ' + (e && e.message || e));
|
|
195
|
-
return { exitCode: 1, error: String(e) };
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
async function runOrders(opts, deps) {
|
|
200
|
-
const atp = (deps && deps.atp) || require('./index');
|
|
201
|
-
const hubClient = atp.hubClient;
|
|
202
|
-
const log = (deps && deps.log) || console.log;
|
|
203
|
-
const err = (deps && deps.err) || console.error;
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
const result = await hubClient.listProofs({
|
|
207
|
-
role: opts.role,
|
|
208
|
-
status: opts.status || undefined,
|
|
209
|
-
limit: opts.limit,
|
|
210
|
-
});
|
|
211
|
-
if (!result.ok) {
|
|
212
|
-
err('[ATP] listProofs failed: ' + (result.error || 'unknown'));
|
|
213
|
-
return { exitCode: 1, data: result };
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const proofs = (result.data && result.data.proofs) || result.data || [];
|
|
217
|
-
if (opts.jsonOut) {
|
|
218
|
-
log(JSON.stringify(proofs, null, 2));
|
|
219
|
-
return { exitCode: 0, data: proofs };
|
|
220
|
-
}
|
|
221
|
-
if (!Array.isArray(proofs) || proofs.length === 0) {
|
|
222
|
-
log('[ATP] No orders found for role=' + opts.role + (opts.status ? ' status=' + opts.status : ''));
|
|
223
|
-
return { exitCode: 0, data: [] };
|
|
224
|
-
}
|
|
225
|
-
log('[ATP] Showing ' + proofs.length + ' order(s):');
|
|
226
|
-
for (const p of proofs) {
|
|
227
|
-
const when = p.createdAt || p.created_at || 'unknown';
|
|
228
|
-
log(' - ' + (p.taskId || p.order_id || p.id) + ' | status=' + p.status + ' | created=' + when);
|
|
229
|
-
}
|
|
230
|
-
return { exitCode: 0, data: proofs };
|
|
231
|
-
} catch (e) {
|
|
232
|
-
err('[ATP] orders error: ' + (e && e.message || e));
|
|
233
|
-
return { exitCode: 1, error: String(e) };
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
async function runVerify(opts, deps) {
|
|
238
|
-
const atp = (deps && deps.atp) || require('./index');
|
|
239
|
-
const consumerAgent = atp.consumerAgent;
|
|
240
|
-
const log = (deps && deps.log) || console.log;
|
|
241
|
-
const err = (deps && deps.err) || console.error;
|
|
242
|
-
|
|
243
|
-
try {
|
|
244
|
-
const fn = opts.action === 'ai_judge' ? consumerAgent.requestAiJudge : consumerAgent.confirmDelivery;
|
|
245
|
-
const result = await fn(opts.orderId);
|
|
246
|
-
if (!result.ok) {
|
|
247
|
-
err('[ATP] verify failed: ' + (result.error || 'unknown'));
|
|
248
|
-
return { exitCode: 1, data: result };
|
|
249
|
-
}
|
|
250
|
-
log('[ATP] verify ok (' + opts.action + '): ' + JSON.stringify(result.data));
|
|
251
|
-
return { exitCode: 0, data: result.data };
|
|
252
|
-
} catch (e) {
|
|
253
|
-
err('[ATP] verify error: ' + (e && e.message || e));
|
|
254
|
-
return { exitCode: 1, error: String(e) };
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Subcommand runner for `evolver atp enable|disable|status`. Writes the ack
|
|
259
|
-
// file via autoBuyer.setConsent so subsequent daemon starts pick it up. Does
|
|
260
|
-
// NOT mutate process.env — env override wins over the ack file by design,
|
|
261
|
-
// and we don't want a transient CLI invocation to silently shadow operator
|
|
262
|
-
// shell config.
|
|
263
|
-
// Detect whether an EVOLVER_ATP_AUTOBUY env override is currently set AND
|
|
264
|
-
// would supersede the ack we are about to write. Returns the effective env
|
|
265
|
-
// boolean (true=on, false=off) or null if env is unset / whitespace-only.
|
|
266
|
-
// Mirrors the trim-before-length-check rule from autoBuyer.getConsent so
|
|
267
|
-
// the CLI and the runtime agree on what "set" means (Bugbot PR #141).
|
|
268
|
-
function _envOverride() {
|
|
269
|
-
const raw = process.env.EVOLVER_ATP_AUTOBUY;
|
|
270
|
-
if (typeof raw !== 'string') return null;
|
|
271
|
-
const s = raw.trim().toLowerCase();
|
|
272
|
-
if (s.length === 0) return null;
|
|
273
|
-
return !(s === 'off' || s === '0' || s === 'false');
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
async function runAtp(opts, deps) {
|
|
277
|
-
const autoBuyer = (deps && deps.autoBuyer) || require('./autoBuyer');
|
|
278
|
-
const log = (deps && deps.log) || console.log;
|
|
279
|
-
const err = (deps && deps.err) || console.error;
|
|
280
|
-
|
|
281
|
-
try {
|
|
282
|
-
if (opts.sub === 'enable') {
|
|
283
|
-
const body = autoBuyer.setConsent(true);
|
|
284
|
-
log('[ATP] auto-spend ENABLED (consent recorded ' + body.acknowledged_at + ').');
|
|
285
|
-
log(' Caps: daily=' + (process.env.ATP_AUTOBUY_DAILY_CAP_CREDITS || '50') +
|
|
286
|
-
', per-order=' + (process.env.ATP_AUTOBUY_PER_ORDER_CAP_CREDITS || '10') + ' credits.');
|
|
287
|
-
log(' Disable: evolver atp disable (or EVOLVER_ATP_AUTOBUY=off)');
|
|
288
|
-
// Loud warning if an env override will silently undo the ack at
|
|
289
|
-
// runtime. Bugbot PR #141 Medium: without this the user gets a
|
|
290
|
-
// false confirmation and real credits keep flowing the wrong way.
|
|
291
|
-
const envEnabled = _envOverride();
|
|
292
|
-
if (envEnabled === false) {
|
|
293
|
-
log('');
|
|
294
|
-
log('[ATP] WARNING: EVOLVER_ATP_AUTOBUY=' + process.env.EVOLVER_ATP_AUTOBUY +
|
|
295
|
-
' is set in your environment and will OVERRIDE the ack file at runtime.');
|
|
296
|
-
log(' Auto-spend will stay OFF until you unset it (env wins over the ack file).');
|
|
297
|
-
return { exitCode: 0, data: body, envOverride: 'off' };
|
|
298
|
-
}
|
|
299
|
-
return { exitCode: 0, data: body };
|
|
300
|
-
}
|
|
301
|
-
if (opts.sub === 'disable') {
|
|
302
|
-
const body = autoBuyer.setConsent(false);
|
|
303
|
-
log('[ATP] auto-spend DISABLED (consent recorded ' + body.acknowledged_at + ').');
|
|
304
|
-
log(' Re-enable: evolver atp enable');
|
|
305
|
-
const envEnabled = _envOverride();
|
|
306
|
-
if (envEnabled === true) {
|
|
307
|
-
log('');
|
|
308
|
-
log('[ATP] WARNING: EVOLVER_ATP_AUTOBUY=' + process.env.EVOLVER_ATP_AUTOBUY +
|
|
309
|
-
' is set in your environment and will OVERRIDE the ack file at runtime.');
|
|
310
|
-
log(' Auto-spend will stay ON (and continue charging credits) until you unset it.');
|
|
311
|
-
return { exitCode: 0, data: body, envOverride: 'on' };
|
|
312
|
-
}
|
|
313
|
-
return { exitCode: 0, data: body };
|
|
314
|
-
}
|
|
315
|
-
// status
|
|
316
|
-
const consent = autoBuyer.getConsent();
|
|
317
|
-
const ackPath = autoBuyer.getAckPath();
|
|
318
|
-
log('[ATP] auto-spend: ' + (consent.enabled ? 'ENABLED' : 'DISABLED') +
|
|
319
|
-
' (source: ' + consent.source + ')');
|
|
320
|
-
log(' ack file: ' + ackPath);
|
|
321
|
-
if (consent.source === 'default') {
|
|
322
|
-
log(' Default policy (no ack file, no env override). Run `evolver atp disable`');
|
|
323
|
-
log(' to opt out, or `evolver atp enable` to record explicit opt-in.');
|
|
324
|
-
}
|
|
325
|
-
return { exitCode: 0, data: consent };
|
|
326
|
-
} catch (e) {
|
|
327
|
-
err('[ATP] atp command error: ' + (e && e.message || e));
|
|
328
|
-
return { exitCode: 1, error: String(e) };
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
function printUsage() {
|
|
333
|
-
return [
|
|
334
|
-
'ATP subcommands:',
|
|
335
|
-
' evolver buy <caps> [--budget=N] [--question "..."] [--routing=' + ATP_ROUTING_MODES.join('|') + ']',
|
|
336
|
-
' [--verify=' + ATP_VERIFY_MODES.join('|') + '] [--no-wait] [--timeout=<seconds>]',
|
|
337
|
-
' evolver orders [--role=' + ATP_ROLES.join('|') + '] [--status=' + ATP_PROOF_STATUSES.join('|') + ']',
|
|
338
|
-
' [--limit=N] [--json]',
|
|
339
|
-
' evolver verify <orderId> [--action=' + ATP_VERIFY_ACTIONS.join('|') + ']',
|
|
340
|
-
' evolver atp <enable|disable|status> -- manage auto-spend consent',
|
|
341
|
-
].join('\n');
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
module.exports = {
|
|
345
|
-
parseBuyArgs,
|
|
346
|
-
parseOrdersArgs,
|
|
347
|
-
parseVerifyArgs,
|
|
348
|
-
parseAtpArgs,
|
|
349
|
-
runBuy,
|
|
350
|
-
runOrders,
|
|
351
|
-
runVerify,
|
|
352
|
-
runAtp,
|
|
353
|
-
printUsage,
|
|
354
|
-
};
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* First-run prompt that introduces the ATP autoBuyer to interactive users.
|
|
5
|
-
*
|
|
6
|
-
* Triggers when ALL conditions hold:
|
|
7
|
-
* - process.stdin.isTTY === true (skipped under systemd, Docker, CI)
|
|
8
|
-
* - EVOLVER_ATP_AUTOBUY is not already set (neither on nor off)
|
|
9
|
-
* - ack file memory/atp-autobuy-ack.json does not exist (already decided)
|
|
10
|
-
*
|
|
11
|
-
* Outcomes:
|
|
12
|
-
* - user answers y -> autoBuyer.setConsent(true) — opts in for future sessions
|
|
13
|
-
* - user answers n -> autoBuyer.setConsent(false) — prompt never shown again
|
|
14
|
-
* - user answers later -> no ack written, prompt shown next session
|
|
15
|
-
* - any non-TTY/ack branch -> silent no-op
|
|
16
|
-
*
|
|
17
|
-
* setConsent failures (FS permission, disk full) are surfaced to the user
|
|
18
|
-
* via the output stream and returned as `reason: 'ack_write_failed'`; the
|
|
19
|
-
* decision field still reflects what the user typed.
|
|
20
|
-
*/
|
|
21
|
-
|
|
22
|
-
const readline = require("readline");
|
|
23
|
-
const autoBuyer = require("./autoBuyer");
|
|
24
|
-
|
|
25
|
-
// All ack file plumbing lives on autoBuyer (filename constant, path
|
|
26
|
-
// resolution, read with strict validation, atomic write via tmp+rename).
|
|
27
|
-
// cliAutobuyPrompt always reaches it through the public surface so the
|
|
28
|
-
// two modules cannot diverge on schema or validation — pre-consolidation
|
|
29
|
-
// drift bit us twice (Bugbot PR #141: duplicate writers + lenient-vs-
|
|
30
|
-
// strict reader). No __internals re-export here either: tests import
|
|
31
|
-
// autoBuyer directly so a future rename trips a single set of asserts.
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @returns {"ack_present"|"env_set"|"non_tty"|"eligible"}
|
|
35
|
-
*/
|
|
36
|
-
function classify(env, stdin) {
|
|
37
|
-
const envVal = env && env.EVOLVER_ATP_AUTOBUY;
|
|
38
|
-
if (typeof envVal === "string" && envVal.trim().length > 0) {
|
|
39
|
-
return "env_set";
|
|
40
|
-
}
|
|
41
|
-
if (!stdin || !stdin.isTTY) {
|
|
42
|
-
return "non_tty";
|
|
43
|
-
}
|
|
44
|
-
if (autoBuyer.readAck()) {
|
|
45
|
-
return "ack_present";
|
|
46
|
-
}
|
|
47
|
-
return "eligible";
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function _ask(question, { input, output }) {
|
|
51
|
-
return new Promise((resolve) => {
|
|
52
|
-
const rl = readline.createInterface({ input, output });
|
|
53
|
-
rl.question(question, (answer) => {
|
|
54
|
-
rl.close();
|
|
55
|
-
resolve((answer || "").trim().toLowerCase());
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Synchronously decide whether to prompt (TTY + no ack + env unset) and,
|
|
62
|
-
* if prompting, block on user answer. Resolves with:
|
|
63
|
-
* { prompted: bool, decision: "yes"|"no"|"later"|null, reason: string }
|
|
64
|
-
*
|
|
65
|
-
* Should be called at most once per `evolver run` invocation, BEFORE the
|
|
66
|
-
* autoBuyer.start() branch in the run loop.
|
|
67
|
-
*
|
|
68
|
-
* @param {object} [opts]
|
|
69
|
-
* @param {NodeJS.ReadableStream} [opts.input]
|
|
70
|
-
* @param {NodeJS.WritableStream} [opts.output]
|
|
71
|
-
* @param {NodeJS.ProcessEnv} [opts.env]
|
|
72
|
-
* @param {(q: string, io: object) => Promise<string>} [opts.ask]
|
|
73
|
-
* @returns {Promise<{ prompted: boolean, decision: string|null, reason: string }>}
|
|
74
|
-
*/
|
|
75
|
-
async function runPrompt(opts) {
|
|
76
|
-
opts = opts || {};
|
|
77
|
-
const input = opts.input || process.stdin;
|
|
78
|
-
const output = opts.output || process.stdout;
|
|
79
|
-
const env = opts.env || process.env;
|
|
80
|
-
const ask = typeof opts.ask === "function" ? opts.ask : _ask;
|
|
81
|
-
|
|
82
|
-
const state = classify(env, input);
|
|
83
|
-
if (state !== "eligible") {
|
|
84
|
-
return { prompted: false, decision: null, reason: state };
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
try {
|
|
88
|
-
output.write("\n");
|
|
89
|
-
output.write("[ATP-AutoBuyer] Your evolver will automatically place small-priced\n");
|
|
90
|
-
output.write("ATP orders when it detects a capability gap. This spends real\n");
|
|
91
|
-
output.write("credits on the EvoMap hub and is ON by default for new installs.\n");
|
|
92
|
-
output.write(" - daily hard cap: ATP_AUTOBUY_DAILY_CAP_CREDITS (default 50)\n");
|
|
93
|
-
output.write(" - per-order cap: ATP_AUTOBUY_PER_ORDER_CAP_CREDITS (default 10)\n");
|
|
94
|
-
output.write(" - change later: evolver atp enable | evolver atp disable\n");
|
|
95
|
-
output.write("\n");
|
|
96
|
-
} catch (_) {
|
|
97
|
-
return { prompted: false, decision: null, reason: "io_error" };
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
let answer;
|
|
101
|
-
try {
|
|
102
|
-
answer = await ask("Keep ATP auto-spend ON for future sessions? [y=keep enabled / n=disable / later=ask again next session] ", {
|
|
103
|
-
input,
|
|
104
|
-
output,
|
|
105
|
-
});
|
|
106
|
-
} catch (_) {
|
|
107
|
-
return { prompted: true, decision: null, reason: "ask_error" };
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// For y/n we persist via autoBuyer.setConsent (atomic tmp+rename, throws
|
|
111
|
-
// on FS failure). If the write fails we MUST tell the user — for the 'n'
|
|
112
|
-
// path especially, since auto-spend is default-ON and a failed disable
|
|
113
|
-
// means the user typed "off" but the runtime keeps charging credits
|
|
114
|
-
// (Bugbot PR #141 Medium: unchecked ack write). Do NOT mutate process.env
|
|
115
|
-
// on success: that would double-signal and shadow any explicit operator
|
|
116
|
-
// preference set later.
|
|
117
|
-
function _persistConsent(enabled, decision) {
|
|
118
|
-
try {
|
|
119
|
-
autoBuyer.setConsent(enabled);
|
|
120
|
-
return { prompted: true, decision, reason: enabled ? "user_accepted" : "user_declined" };
|
|
121
|
-
} catch (err) {
|
|
122
|
-
try {
|
|
123
|
-
output.write("[ATP-AutoBuyer] WARN: failed to persist consent: " + (err && err.message || err) + "\n");
|
|
124
|
-
if (enabled) {
|
|
125
|
-
output.write(" Auto-spend will keep using the default-on policy until\n");
|
|
126
|
-
output.write(" the ack is saved (capped at the configured caps).\n");
|
|
127
|
-
} else {
|
|
128
|
-
output.write(" Auto-spend will STAY ON (default policy) until your opt-out\n");
|
|
129
|
-
output.write(" can be saved — your decline was not persisted.\n");
|
|
130
|
-
}
|
|
131
|
-
output.write(" Check disk space and write permissions on the memory dir, then run\n");
|
|
132
|
-
output.write(" `evolver atp " + (enabled ? "enable" : "disable") + "` to retry.\n");
|
|
133
|
-
} catch (_) { /* output stream is broken too — nothing more we can do */ }
|
|
134
|
-
return { prompted: true, decision, reason: "ack_write_failed" };
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
if (answer === "y" || answer === "yes") {
|
|
139
|
-
return _persistConsent(true, "yes");
|
|
140
|
-
}
|
|
141
|
-
if (answer === "n" || answer === "no") {
|
|
142
|
-
return _persistConsent(false, "no");
|
|
143
|
-
}
|
|
144
|
-
// Postpone: no ack written, so autoBuyer.getConsent() returns
|
|
145
|
-
// {enabled: true, source: 'default'} this session. Auto-spend keeps
|
|
146
|
-
// running under the default policy with caps; the prompt will fire again
|
|
147
|
-
// next interactive session so the user can confirm or opt out.
|
|
148
|
-
return { prompted: true, decision: "later", reason: "user_postponed" };
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
module.exports = {
|
|
152
|
-
runPrompt,
|
|
153
|
-
classify,
|
|
154
|
-
};
|
package/src/atp/consumerAgent.js
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
// ATP Consumer Agent Template
|
|
2
|
-
// Provides a ready-to-use consumer agent that searches for services,
|
|
3
|
-
// places orders, and manages delivery verification.
|
|
4
|
-
//
|
|
5
|
-
// Usage:
|
|
6
|
-
// const consumer = require('./consumerAgent');
|
|
7
|
-
// const result = await consumer.orderService({ capabilities: ['code_review'], budget: 50 });
|
|
8
|
-
|
|
9
|
-
const { getNodeId, sendHelloToHub } = require('../gep/a2aProtocol');
|
|
10
|
-
const { placeOrder, verifyDelivery, settleOrder, disputeOrder, getOrderStatus, getAtpPolicy } = require('./hubClient');
|
|
11
|
-
|
|
12
|
-
let _initialized = false;
|
|
13
|
-
|
|
14
|
-
async function ensureInitialized() {
|
|
15
|
-
if (_initialized) return;
|
|
16
|
-
const hello = await sendHelloToHub();
|
|
17
|
-
if (!hello || !hello.ok) {
|
|
18
|
-
throw new Error('Failed to register with Hub: ' + (hello?.error || 'unknown'));
|
|
19
|
-
}
|
|
20
|
-
_initialized = true;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Place an ATP order for a service.
|
|
25
|
-
* @param {object} opts
|
|
26
|
-
* @param {string[]} opts.capabilities - what the order needs
|
|
27
|
-
* @param {number} opts.budget - credits to spend
|
|
28
|
-
* @param {string} [opts.routingMode] - fastest | cheapest | auction | swarm
|
|
29
|
-
* @param {string} [opts.verifyMode] - auto | ai_judge | bilateral
|
|
30
|
-
* @param {string} [opts.question] - description of what you need
|
|
31
|
-
* @returns {Promise<{ok: boolean, data?: object, error?: string}>}
|
|
32
|
-
*/
|
|
33
|
-
async function orderService(opts) {
|
|
34
|
-
await ensureInitialized();
|
|
35
|
-
|
|
36
|
-
const result = await placeOrder({
|
|
37
|
-
capabilities: opts.capabilities,
|
|
38
|
-
budget: Math.max(1, Math.round(Number(opts.budget) || 10)),
|
|
39
|
-
routingMode: opts.routingMode || 'fastest',
|
|
40
|
-
verifyMode: opts.verifyMode || 'auto',
|
|
41
|
-
question: opts.question,
|
|
42
|
-
signals: opts.signals,
|
|
43
|
-
minReputation: opts.minReputation,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
if (result.ok) {
|
|
47
|
-
console.log('[ATP-Consumer] Order placed:', result.data.order_id, '-> merchant:', result.data.merchant?.node_id);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return result;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Confirm delivery of an order (bilateral mode).
|
|
55
|
-
* @param {string} orderId
|
|
56
|
-
* @returns {Promise<{ok: boolean, data?: object, error?: string}>}
|
|
57
|
-
*/
|
|
58
|
-
async function confirmDelivery(orderId) {
|
|
59
|
-
await ensureInitialized();
|
|
60
|
-
return verifyDelivery(orderId, 'confirm');
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Request AI judge verification.
|
|
65
|
-
* @param {string} orderId
|
|
66
|
-
* @returns {Promise<{ok: boolean, data?: object, error?: string}>}
|
|
67
|
-
*/
|
|
68
|
-
async function requestAiJudge(orderId) {
|
|
69
|
-
await ensureInitialized();
|
|
70
|
-
return verifyDelivery(orderId, 'ai_judge');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Force settlement of an order.
|
|
75
|
-
* @param {string} orderId
|
|
76
|
-
* @returns {Promise<{ok: boolean, data?: object, error?: string}>}
|
|
77
|
-
*/
|
|
78
|
-
async function settle(orderId) {
|
|
79
|
-
await ensureInitialized();
|
|
80
|
-
return settleOrder(orderId);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* Raise a dispute for an order.
|
|
85
|
-
* @param {string} orderId
|
|
86
|
-
* @param {string} reason - min 10 chars
|
|
87
|
-
* @returns {Promise<{ok: boolean, data?: object, error?: string}>}
|
|
88
|
-
*/
|
|
89
|
-
async function dispute(orderId, reason) {
|
|
90
|
-
await ensureInitialized();
|
|
91
|
-
return disputeOrder(orderId, reason);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Check the status of an order.
|
|
96
|
-
* @param {string} orderId
|
|
97
|
-
* @returns {Promise<{ok: boolean, data?: object, error?: string}>}
|
|
98
|
-
*/
|
|
99
|
-
async function checkOrder(orderId) {
|
|
100
|
-
return getOrderStatus(orderId);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Get ATP policy information (tiers, rates, etc.)
|
|
105
|
-
* @returns {Promise<{ok: boolean, data?: object, error?: string}>}
|
|
106
|
-
*/
|
|
107
|
-
async function getPolicy() {
|
|
108
|
-
return getAtpPolicy();
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Full order lifecycle: place -> wait -> verify -> settle.
|
|
113
|
-
* @param {object} opts - same as orderService
|
|
114
|
-
* @param {number} [opts.pollIntervalMs] - how often to check status (default 10s)
|
|
115
|
-
* @param {number} [opts.timeoutMs] - max wait time (default 300s)
|
|
116
|
-
* @returns {Promise<{ok: boolean, order?: object, finalStatus?: object, error?: string}>}
|
|
117
|
-
*/
|
|
118
|
-
async function orderAndWait(opts) {
|
|
119
|
-
const order = await orderService(opts);
|
|
120
|
-
if (!order.ok) return order;
|
|
121
|
-
|
|
122
|
-
const orderId = order.data.order_id;
|
|
123
|
-
const pollMs = opts.pollIntervalMs || 10000;
|
|
124
|
-
const timeoutMs = opts.timeoutMs || 300000;
|
|
125
|
-
const deadline = Date.now() + timeoutMs;
|
|
126
|
-
|
|
127
|
-
while (Date.now() < deadline) {
|
|
128
|
-
await new Promise(resolve => setTimeout(resolve, pollMs));
|
|
129
|
-
|
|
130
|
-
const status = await checkOrder(orderId);
|
|
131
|
-
if (!status.ok) continue;
|
|
132
|
-
|
|
133
|
-
const proofStatus = status.data.proof_status;
|
|
134
|
-
if (proofStatus === 'settled') {
|
|
135
|
-
return { ok: true, order: order.data, finalStatus: status.data };
|
|
136
|
-
}
|
|
137
|
-
if (proofStatus === 'verified' && order.data.verify_mode === 'auto') {
|
|
138
|
-
return { ok: true, order: order.data, finalStatus: status.data };
|
|
139
|
-
}
|
|
140
|
-
if (proofStatus === 'disputed') {
|
|
141
|
-
return { ok: false, order: order.data, finalStatus: status.data, error: 'order_disputed' };
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return { ok: false, order: order.data, error: 'order_timeout' };
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
module.exports = {
|
|
149
|
-
orderService,
|
|
150
|
-
confirmDelivery,
|
|
151
|
-
requestAiJudge,
|
|
152
|
-
settle,
|
|
153
|
-
dispute,
|
|
154
|
-
checkOrder,
|
|
155
|
-
getPolicy,
|
|
156
|
-
orderAndWait,
|
|
157
|
-
};
|