thumbgate 1.15.0 → 1.16.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/.claude-plugin/marketplace.json +6 -6
- package/.claude-plugin/plugin.json +3 -3
- package/.well-known/llms.txt +5 -5
- package/.well-known/mcp/server-card.json +1 -1
- package/README.md +59 -35
- package/adapters/chatgpt/openapi.yaml +118 -2
- package/adapters/claude/.mcp.json +2 -2
- package/adapters/mcp/server-stdio.js +210 -84
- package/adapters/opencode/opencode.json +1 -1
- package/bench/prompt-eval-suite.json +5 -1
- package/bin/cli.js +157 -8
- package/config/evals/agent-safety-eval.json +338 -22
- package/config/gates/routine.json +43 -0
- package/config/github-about.json +3 -3
- package/config/model-candidates.json +131 -0
- package/openapi/openapi.yaml +118 -2
- package/package.json +57 -49
- package/public/blog.html +7 -7
- package/public/codex-plugin.html +6 -6
- package/public/compare.html +29 -23
- package/public/dashboard.html +82 -10
- package/public/guide.html +28 -28
- package/public/index.html +216 -98
- package/public/learn.html +50 -22
- package/public/lessons.html +1 -1
- package/public/numbers.html +17 -17
- package/public/pro.html +82 -18
- package/scripts/agent-audit-trace.js +55 -0
- package/scripts/agent-memory-lifecycle.js +96 -0
- package/scripts/agent-readiness-plan.js +118 -0
- package/scripts/agentic-data-pipeline.js +21 -1
- package/scripts/agents-sdk-sandbox-plan.js +57 -0
- package/scripts/ai-org-governance.js +98 -0
- package/scripts/ai-search-distribution.js +43 -0
- package/scripts/artifact-agent-plan.js +81 -0
- package/scripts/billing.js +27 -8
- package/scripts/cli-schema.js +18 -2
- package/scripts/code-mode-mcp-plan.js +71 -0
- package/scripts/context-engine.js +1 -2
- package/scripts/context-manager.js +4 -1
- package/scripts/dashboard-render-spec.js +1 -1
- package/scripts/dashboard.js +275 -9
- package/scripts/decision-journal.js +13 -3
- package/scripts/document-workflow-governance.js +62 -0
- package/scripts/enterprise-agent-rollout.js +34 -0
- package/scripts/experience-replay-governance.js +69 -0
- package/scripts/export-hf-dataset.js +1 -1
- package/scripts/feedback-loop.js +92 -4
- package/scripts/feedback-to-rules.js +17 -23
- package/scripts/gates-engine.js +4 -6
- package/scripts/growth-campaigns.js +49 -0
- package/scripts/harness-selector.js +16 -4
- package/scripts/hybrid-supervisor-agent.js +64 -0
- package/scripts/inference-cache-policy.js +72 -0
- package/scripts/inference-economics.js +53 -0
- package/scripts/internal-agent-bootstrap.js +12 -2
- package/scripts/knowledge-layer-plan.js +108 -0
- package/scripts/lesson-inference.js +183 -44
- package/scripts/lesson-search.js +4 -1
- package/scripts/llm-client.js +157 -26
- package/scripts/mailer/resend-mailer.js +112 -1
- package/scripts/mcp-transport-strategy.js +66 -0
- package/scripts/memory-store-governance.js +60 -0
- package/scripts/meta-agent-loop.js +7 -13
- package/scripts/model-access-eligibility.js +38 -0
- package/scripts/model-migration-readiness.js +55 -0
- package/scripts/operational-integrity.js +96 -3
- package/scripts/otel-declarative-config.js +56 -0
- package/scripts/perplexity-client.js +1 -1
- package/scripts/post-training-governance.js +34 -0
- package/scripts/private-core-boundary.js +72 -0
- package/scripts/production-agent-readiness.js +40 -0
- package/scripts/prompt-eval.js +564 -32
- package/scripts/prompt-programs.js +93 -0
- package/scripts/provider-action-normalizer.js +585 -0
- package/scripts/scaling-law-claims.js +60 -0
- package/scripts/security-scanner.js +1 -1
- package/scripts/self-distill-agent.js +7 -32
- package/scripts/seo-gsd.js +232 -55
- package/scripts/skill-rag-router.js +53 -0
- package/scripts/spec-gate.js +1 -1
- package/scripts/student-consistent-training.js +73 -0
- package/scripts/synthetic-data-provenance.js +98 -0
- package/scripts/task-context-result.js +81 -0
- package/scripts/telemetry-analytics.js +149 -0
- package/scripts/thompson-sampling.js +2 -2
- package/scripts/token-savings.js +7 -6
- package/scripts/token-tco.js +46 -0
- package/scripts/tool-registry.js +63 -3
- package/scripts/verification-loop.js +10 -1
- package/scripts/verifier-scoring.js +71 -0
- package/scripts/workflow-sentinel.js +284 -28
- package/scripts/workspace-agent-routines.js +118 -0
- package/src/api/server.js +381 -120
- package/scripts/analytics-report.js +0 -328
- package/scripts/autonomous-workflow.js +0 -377
- package/scripts/billing-setup.js +0 -109
- package/scripts/creator-campaigns.js +0 -239
- package/scripts/cross-encoder-reranker.js +0 -235
- package/scripts/daemon-manager.js +0 -108
- package/scripts/decision-trace.js +0 -354
- package/scripts/delegation-runtime.js +0 -896
- package/scripts/dispatch-brief.js +0 -159
- package/scripts/distribution-surfaces.js +0 -110
- package/scripts/feedback-history-distiller.js +0 -382
- package/scripts/funnel-analytics.js +0 -35
- package/scripts/history-distiller.js +0 -200
- package/scripts/hosted-job-launcher.js +0 -256
- package/scripts/intent-router.js +0 -392
- package/scripts/lesson-reranker.js +0 -263
- package/scripts/lesson-retrieval.js +0 -148
- package/scripts/managed-lesson-agent.js +0 -183
- package/scripts/operational-dashboard.js +0 -103
- package/scripts/operational-summary.js +0 -129
- package/scripts/operator-artifacts.js +0 -608
- package/scripts/optimize-context.js +0 -17
- package/scripts/org-dashboard.js +0 -206
- package/scripts/partner-orchestration.js +0 -146
- package/scripts/predictive-insights.js +0 -356
- package/scripts/pulse.js +0 -80
- package/scripts/reflector-agent.js +0 -221
- package/scripts/sales-pipeline.js +0 -681
- package/scripts/session-episode-store.js +0 -329
- package/scripts/session-health-sensor.js +0 -242
- package/scripts/session-report.js +0 -120
- package/scripts/swarm-coordinator.js +0 -81
- package/scripts/tool-kpi-tracker.js +0 -12
- package/scripts/webhook-delivery.js +0 -62
- package/scripts/workflow-sprint-intake.js +0 -475
package/scripts/org-dashboard.js
DELETED
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Org Dashboard — Multi-Agent Orchestration Visibility
|
|
6
|
-
*
|
|
7
|
-
* Aggregates gate decisions, audit trails, and session data across
|
|
8
|
-
* multiple agent sessions into a single org-wide view. CIOs want to
|
|
9
|
-
* see what ALL their agents are doing, not just one at a time.
|
|
10
|
-
*
|
|
11
|
-
* "I'm not going to have 10,000 agents running in the environment
|
|
12
|
-
* that I don't know what they're doing" — CIO.com, March 2026
|
|
13
|
-
*
|
|
14
|
-
* Pro feature: free tier gets single-agent dashboard only.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
const fs = require('fs');
|
|
18
|
-
const path = require('path');
|
|
19
|
-
const { resolveFeedbackDir } = require('./feedback-paths');
|
|
20
|
-
const { readAuditLog, auditStats, skillAdherence } = require('./audit-trail');
|
|
21
|
-
const { isProTier } = require('./rate-limiter');
|
|
22
|
-
const {
|
|
23
|
-
PRO_MONTHLY_PAYMENT_LINK,
|
|
24
|
-
PRO_PRICE_LABEL,
|
|
25
|
-
TEAM_PRICE_LABEL,
|
|
26
|
-
} = require('./commercial-offer');
|
|
27
|
-
|
|
28
|
-
// ---------------------------------------------------------------------------
|
|
29
|
-
// Agent Registry
|
|
30
|
-
// ---------------------------------------------------------------------------
|
|
31
|
-
|
|
32
|
-
const REGISTRY_FILENAME = 'agent-registry.jsonl';
|
|
33
|
-
|
|
34
|
-
function getRegistryPath() {
|
|
35
|
-
return path.join(resolveFeedbackDir(), REGISTRY_FILENAME);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Register an agent session. Called on MCP server startup or agent bootstrap.
|
|
40
|
-
*
|
|
41
|
-
* @param {object} params
|
|
42
|
-
* @param {string} params.agentId - Unique agent identifier
|
|
43
|
-
* @param {string} [params.source] - Where the agent was spawned from (cli, mcp, github, slack)
|
|
44
|
-
* @param {string} [params.project] - Project/repo name
|
|
45
|
-
* @param {string} [params.branch] - Git branch
|
|
46
|
-
* @param {object} [params.metadata] - Arbitrary metadata
|
|
47
|
-
* @returns {object} The registered agent record
|
|
48
|
-
*/
|
|
49
|
-
function registerAgent({ agentId, source, project, branch, metadata } = {}) {
|
|
50
|
-
const id = agentId || `agent_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
51
|
-
const record = {
|
|
52
|
-
id,
|
|
53
|
-
registeredAt: new Date().toISOString(),
|
|
54
|
-
lastSeenAt: new Date().toISOString(),
|
|
55
|
-
source: source || 'unknown',
|
|
56
|
-
project: project || path.basename(process.cwd()),
|
|
57
|
-
branch: branch || null,
|
|
58
|
-
toolCalls: 0,
|
|
59
|
-
gateBlocks: 0,
|
|
60
|
-
gateWarns: 0,
|
|
61
|
-
metadata: metadata || {},
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const registryPath = getRegistryPath();
|
|
65
|
-
const dir = path.dirname(registryPath);
|
|
66
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
67
|
-
fs.appendFileSync(registryPath, JSON.stringify(record) + '\n');
|
|
68
|
-
return record;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Record agent activity — called after each tool call evaluation.
|
|
73
|
-
*
|
|
74
|
-
* @param {string} agentId
|
|
75
|
-
* @param {string} decision - 'allow' | 'deny' | 'warn'
|
|
76
|
-
*/
|
|
77
|
-
function recordAgentActivity(agentId, decision) {
|
|
78
|
-
const registryPath = getRegistryPath();
|
|
79
|
-
if (!fs.existsSync(registryPath)) return;
|
|
80
|
-
|
|
81
|
-
const lines = fs.readFileSync(registryPath, 'utf-8').trim().split('\n');
|
|
82
|
-
const updated = [];
|
|
83
|
-
let found = false;
|
|
84
|
-
|
|
85
|
-
for (const line of lines) {
|
|
86
|
-
try {
|
|
87
|
-
const record = JSON.parse(line);
|
|
88
|
-
if (record.id === agentId && !found) {
|
|
89
|
-
record.lastSeenAt = new Date().toISOString();
|
|
90
|
-
record.toolCalls = (record.toolCalls || 0) + 1;
|
|
91
|
-
if (decision === 'deny') record.gateBlocks = (record.gateBlocks || 0) + 1;
|
|
92
|
-
if (decision === 'warn') record.gateWarns = (record.gateWarns || 0) + 1;
|
|
93
|
-
found = true;
|
|
94
|
-
}
|
|
95
|
-
updated.push(JSON.stringify(record));
|
|
96
|
-
} catch {
|
|
97
|
-
updated.push(line);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
fs.writeFileSync(registryPath, updated.join('\n') + '\n');
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Load all registered agent sessions.
|
|
106
|
-
*/
|
|
107
|
-
function loadAgentRegistry() {
|
|
108
|
-
const registryPath = getRegistryPath();
|
|
109
|
-
if (!fs.existsSync(registryPath)) return [];
|
|
110
|
-
const raw = fs.readFileSync(registryPath, 'utf-8').trim();
|
|
111
|
-
if (!raw) return [];
|
|
112
|
-
return raw.split('\n').map(line => {
|
|
113
|
-
try { return JSON.parse(line); }
|
|
114
|
-
catch { return null; }
|
|
115
|
-
}).filter(Boolean);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// ---------------------------------------------------------------------------
|
|
119
|
-
// Org Dashboard Aggregation
|
|
120
|
-
// ---------------------------------------------------------------------------
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Generate org-wide dashboard aggregating all agent sessions.
|
|
124
|
-
* Pro feature — returns limited data on free tier.
|
|
125
|
-
*
|
|
126
|
-
* @param {object} [opts]
|
|
127
|
-
* @param {number} [opts.windowHours=24] - Lookback window in hours
|
|
128
|
-
* @returns {object} Org dashboard data
|
|
129
|
-
*/
|
|
130
|
-
function generateOrgDashboard(opts = {}) {
|
|
131
|
-
const windowHours = opts.windowHours || 24;
|
|
132
|
-
const cutoff = Date.now() - windowHours * 60 * 60 * 1000;
|
|
133
|
-
const pro = typeof opts.proOverride === 'boolean'
|
|
134
|
-
? opts.proOverride
|
|
135
|
-
: isProTier(opts.authContext);
|
|
136
|
-
|
|
137
|
-
// Load all agents
|
|
138
|
-
const allAgents = loadAgentRegistry();
|
|
139
|
-
const activeAgents = allAgents.filter(a => new Date(a.lastSeenAt).getTime() > cutoff);
|
|
140
|
-
|
|
141
|
-
// Aggregate audit trail
|
|
142
|
-
const audit = auditStats();
|
|
143
|
-
const adherence = skillAdherence();
|
|
144
|
-
|
|
145
|
-
// Per-agent summary
|
|
146
|
-
const agentSummaries = activeAgents.map(a => ({
|
|
147
|
-
id: a.id,
|
|
148
|
-
source: a.source,
|
|
149
|
-
project: a.project,
|
|
150
|
-
branch: a.branch,
|
|
151
|
-
registeredAt: a.registeredAt,
|
|
152
|
-
lastSeenAt: a.lastSeenAt,
|
|
153
|
-
toolCalls: a.toolCalls || 0,
|
|
154
|
-
gateBlocks: a.gateBlocks || 0,
|
|
155
|
-
gateWarns: a.gateWarns || 0,
|
|
156
|
-
adherenceRate: a.toolCalls > 0
|
|
157
|
-
? Math.round(((a.toolCalls - (a.gateBlocks || 0) - (a.gateWarns || 0)) / a.toolCalls) * 10000) / 100
|
|
158
|
-
: 100,
|
|
159
|
-
}));
|
|
160
|
-
|
|
161
|
-
// Top blocked gates across all agents
|
|
162
|
-
const topBlockedGates = Object.entries(audit.byGate || {})
|
|
163
|
-
.map(([gateId, counts]) => ({ gateId, blocked: counts.deny || 0, warned: counts.warn || 0 }))
|
|
164
|
-
.sort((a, b) => b.blocked - a.blocked)
|
|
165
|
-
.slice(0, 10);
|
|
166
|
-
|
|
167
|
-
// Risk agents — those with lowest adherence
|
|
168
|
-
const riskAgents = agentSummaries
|
|
169
|
-
.filter(a => a.toolCalls >= 3)
|
|
170
|
-
.sort((a, b) => a.adherenceRate - b.adherenceRate)
|
|
171
|
-
.slice(0, 5);
|
|
172
|
-
|
|
173
|
-
const summary = {
|
|
174
|
-
windowHours,
|
|
175
|
-
totalAgents: allAgents.length,
|
|
176
|
-
activeAgents: activeAgents.length,
|
|
177
|
-
totalToolCalls: audit.total,
|
|
178
|
-
totalBlocked: audit.deny,
|
|
179
|
-
totalWarned: audit.warn,
|
|
180
|
-
totalAllowed: audit.allow,
|
|
181
|
-
orgAdherenceRate: adherence.overall,
|
|
182
|
-
topBlockedGates,
|
|
183
|
-
riskAgents: pro ? riskAgents : riskAgents.slice(0, 1),
|
|
184
|
-
agents: pro ? agentSummaries : agentSummaries.slice(0, 3),
|
|
185
|
-
proRequired: !pro,
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
if (!pro) {
|
|
189
|
-
summary.upgradeMessage = `Pro checkout: ${PRO_PRICE_LABEL} — ${PRO_MONTHLY_PAYMENT_LINK} | Team: ${TEAM_PRICE_LABEL} after workflow qualification.`;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return summary;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// ---------------------------------------------------------------------------
|
|
196
|
-
// Exports
|
|
197
|
-
// ---------------------------------------------------------------------------
|
|
198
|
-
|
|
199
|
-
module.exports = {
|
|
200
|
-
registerAgent,
|
|
201
|
-
recordAgentActivity,
|
|
202
|
-
loadAgentRegistry,
|
|
203
|
-
generateOrgDashboard,
|
|
204
|
-
getRegistryPath,
|
|
205
|
-
REGISTRY_FILENAME,
|
|
206
|
-
};
|
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
const PROJECT_ROOT = path.join(__dirname, '..');
|
|
7
|
-
const DEFAULT_CONFIG_PATH = path.join(PROJECT_ROOT, 'config', 'partner-routing.json');
|
|
8
|
-
|
|
9
|
-
function clamp(value, min, max) {
|
|
10
|
-
return Math.min(max, Math.max(min, value));
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function loadPartnerRoutingConfig(configPath = DEFAULT_CONFIG_PATH) {
|
|
14
|
-
const raw = fs.readFileSync(configPath, 'utf-8');
|
|
15
|
-
const parsed = JSON.parse(raw);
|
|
16
|
-
|
|
17
|
-
if (!parsed || typeof parsed !== 'object') {
|
|
18
|
-
throw new Error('Invalid partner routing config: expected object');
|
|
19
|
-
}
|
|
20
|
-
if (!parsed.defaultProfile || typeof parsed.defaultProfile !== 'string') {
|
|
21
|
-
throw new Error('Invalid partner routing config: missing defaultProfile');
|
|
22
|
-
}
|
|
23
|
-
if (!parsed.profiles || typeof parsed.profiles !== 'object') {
|
|
24
|
-
throw new Error('Invalid partner routing config: missing profiles');
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return parsed;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function normalizePartnerProfile(partnerProfile, config = loadPartnerRoutingConfig()) {
|
|
31
|
-
if (!partnerProfile) {
|
|
32
|
-
return config.defaultProfile;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const raw = String(partnerProfile).trim().toLowerCase();
|
|
36
|
-
const alias = config.aliases && config.aliases[raw];
|
|
37
|
-
const resolved = alias || raw;
|
|
38
|
-
|
|
39
|
-
if (!config.profiles[resolved]) {
|
|
40
|
-
throw new Error(`Unknown partner profile: ${partnerProfile}`);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return resolved;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function getPartnerCategory(partnerProfile) {
|
|
47
|
-
return `partner_${partnerProfile}`;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function scaleBudgetValue(value, multiplier) {
|
|
51
|
-
if (!Number.isFinite(value) || value <= 0) {
|
|
52
|
-
return value;
|
|
53
|
-
}
|
|
54
|
-
const effectiveMultiplier = Number.isFinite(multiplier) && multiplier > 0 ? multiplier : 1;
|
|
55
|
-
return Math.max(1, Math.round(value * effectiveMultiplier));
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function scaleTokenBudget(tokenBudget, multipliers = {}) {
|
|
59
|
-
if (!tokenBudget || typeof tokenBudget !== 'object') {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return {
|
|
64
|
-
total: scaleBudgetValue(tokenBudget.total, multipliers.total),
|
|
65
|
-
perAction: scaleBudgetValue(tokenBudget.perAction, multipliers.perAction),
|
|
66
|
-
contextPack: scaleBudgetValue(tokenBudget.contextPack, multipliers.contextPack),
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function buildPartnerStrategy(options = {}) {
|
|
71
|
-
const config = loadPartnerRoutingConfig(options.configPath);
|
|
72
|
-
const profile = normalizePartnerProfile(options.partnerProfile, config);
|
|
73
|
-
const profileConfig = config.profiles[profile] || {};
|
|
74
|
-
|
|
75
|
-
return {
|
|
76
|
-
profile,
|
|
77
|
-
label: profileConfig.label || profile,
|
|
78
|
-
description: profileConfig.description || '',
|
|
79
|
-
verificationMode: profileConfig.verificationMode || 'standard',
|
|
80
|
-
maxRetryDelta: Number.isFinite(profileConfig.maxRetryDelta) ? profileConfig.maxRetryDelta : 0,
|
|
81
|
-
rewardBias: Number.isFinite(profileConfig.rewardBias) ? profileConfig.rewardBias : 0,
|
|
82
|
-
partnerCategory: getPartnerCategory(profile),
|
|
83
|
-
actionBiases: profileConfig.actionBiases || {},
|
|
84
|
-
recommendedChecks: Array.isArray(profileConfig.recommendedChecks) ? profileConfig.recommendedChecks.slice() : [],
|
|
85
|
-
tokenBudget: scaleTokenBudget(options.tokenBudget, profileConfig.tokenBudgetMultiplier || {}),
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function getPartnerActionBias(action, partnerStrategy) {
|
|
90
|
-
if (!action || !partnerStrategy || !partnerStrategy.actionBiases) {
|
|
91
|
-
return 0;
|
|
92
|
-
}
|
|
93
|
-
return Number(partnerStrategy.actionBiases[action.name] || 0);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function resolveVerificationRetries(baseMaxRetries, partnerStrategy) {
|
|
97
|
-
const requested = Number.isFinite(baseMaxRetries) ? baseMaxRetries : 3;
|
|
98
|
-
const delta = partnerStrategy && Number.isFinite(partnerStrategy.maxRetryDelta)
|
|
99
|
-
? partnerStrategy.maxRetryDelta
|
|
100
|
-
: 0;
|
|
101
|
-
return Math.max(1, requested + delta);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function computePartnerReward(params = {}) {
|
|
105
|
-
const config = loadPartnerRoutingConfig(params.configPath);
|
|
106
|
-
const rewardModel = config.rewardModel || {};
|
|
107
|
-
const accepted = params.accepted === true;
|
|
108
|
-
const attempts = Number.isFinite(params.attempts) ? params.attempts : 1;
|
|
109
|
-
const violationCount = Number.isFinite(params.violationCount) ? params.violationCount : 0;
|
|
110
|
-
const partnerStrategy = params.partnerStrategy || buildPartnerStrategy({
|
|
111
|
-
partnerProfile: params.partnerProfile,
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
const baseReward = accepted ? Number(rewardModel.accepted || 1) : Number(rewardModel.rejected || -1);
|
|
115
|
-
const attemptPenalty = Math.max(0, attempts - 1) * Number(rewardModel.attemptPenalty || 0);
|
|
116
|
-
const violationPenalty = Math.min(
|
|
117
|
-
violationCount * Number(rewardModel.violationPenalty || 0),
|
|
118
|
-
Number(rewardModel.maxViolationPenalty || 0),
|
|
119
|
-
);
|
|
120
|
-
const rawReward = baseReward - attemptPenalty - violationPenalty + Number(partnerStrategy.rewardBias || 0);
|
|
121
|
-
const reward = Math.round(clamp(rawReward, -1, 1) * 1000) / 1000;
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
profile: partnerStrategy.profile,
|
|
125
|
-
reward,
|
|
126
|
-
weightMultiplier: 1 + Math.abs(reward),
|
|
127
|
-
components: {
|
|
128
|
-
baseReward,
|
|
129
|
-
attemptPenalty,
|
|
130
|
-
violationPenalty,
|
|
131
|
-
rewardBias: Number(partnerStrategy.rewardBias || 0),
|
|
132
|
-
},
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
module.exports = {
|
|
137
|
-
DEFAULT_CONFIG_PATH,
|
|
138
|
-
loadPartnerRoutingConfig,
|
|
139
|
-
normalizePartnerProfile,
|
|
140
|
-
getPartnerCategory,
|
|
141
|
-
scaleTokenBudget,
|
|
142
|
-
buildPartnerStrategy,
|
|
143
|
-
getPartnerActionBias,
|
|
144
|
-
resolveVerificationRetries,
|
|
145
|
-
computePartnerReward,
|
|
146
|
-
};
|