@agent-e/core 1.5.7 → 1.5.9

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 CHANGED
@@ -1,6 +1,8 @@
1
- # @agent-e/core
1
+ # AgentE — Autonomous Economic Balancer
2
2
 
3
- Autonomous economic balancer SDK. 60 built-in principles, 5-stage pipeline, zero dependencies. Works with any digital economy.
3
+ > 60 principles. 5-stage pipeline. One npm install. Any economy.
4
+
5
+ AgentE observes, diagnoses, simulates, plans, and executes — keeping any digital economy healthy without manual tuning. If it has currencies, resources, and participants, AgentE balances it.
4
6
 
5
7
  ## Install
6
8
 
@@ -15,187 +17,163 @@ import { AgentE } from '@agent-e/core';
15
17
 
16
18
  const agent = new AgentE({
17
19
  adapter: {
20
+ // AgentE calls this every tick.
21
+ // Return a snapshot of your economy — from YOUR database/API.
18
22
  getState: () => ({
19
- tick: currentTick,
20
- currencies: ['currency_a', 'currency_b'],
21
- systems: ['system_1', 'system_2'],
22
- agentBalances: {
23
- agent_001: { currency_a: 500, currency_b: 20 },
24
- agent_002: { currency_a: 120, currency_b: 80 },
25
- },
26
- agentRoles: { agent_001: 'role_a', agent_002: 'role_b' },
27
- marketPrices: {
28
- currency_a: { resource_x: 10, resource_y: 25 },
29
- },
30
- agentSatisfaction: { agent_001: 72, agent_002: 85 },
31
- poolSizes: { main_pool: { currency_a: 5000 } },
32
- roles: ['role_a', 'role_b'],
33
- resources: ['resource_x', 'resource_y'],
34
- recentTransactions: [],
23
+ tick: getCurrentTick(),
24
+ currencies: getCurrencies(), // e.g. ['gold', 'gems']
25
+ systems: getSystems(), // e.g. ['crafting', 'arena']
26
+ roles: getRoles(), // e.g. ['warrior', 'merchant']
27
+ resources: getResources(), // e.g. ['ore', 'wood']
28
+ agentBalances: getBalances(), // agent currency amount
29
+ agentRoles: getAgentRoles(), // agent → role
30
+ marketPrices: getPrices(), // currency resource price
31
+ recentTransactions: getTxns(),
35
32
  }),
33
+
34
+ // AgentE tells you WHAT to change — you apply it
36
35
  setParam: async (param, value, scope) => {
37
36
  applyToYourEconomy(param, value, scope);
38
37
  },
39
38
  },
39
+
40
+ // Register YOUR economy's tunable parameters
40
41
  parameters: [
41
- { key: 'your_fee_param', type: 'fee', flowImpact: 'friction', scope: { system: 'system_1' } },
42
- { key: 'your_reward_param', type: 'reward', flowImpact: 'faucet', scope: { system: 'system_2' } },
42
+ { key: 'crafting_cost', type: 'cost', flowImpact: 'sink' },
43
+ { key: 'arena_reward', type: 'reward', flowImpact: 'faucet' },
44
+ { key: 'market_fee', type: 'fee', flowImpact: 'friction' },
43
45
  ],
46
+
44
47
  mode: 'advisor',
48
+ onDecision: (d) => console.log(d),
45
49
  });
46
50
 
47
51
  agent.start();
52
+
53
+ // In your loop:
48
54
  await agent.tick();
49
55
  ```
50
56
 
51
- **Replace the placeholder names with YOUR economy's actual names.** See the root README for real-world examples (game, DeFi, marketplace).
52
-
53
- ## The 5-Stage Pipeline
57
+ > **You never hand-type agents.** `getState()` pulls from your existing backend — whether that's 50 players or 5 million. AgentE computes aggregate metrics (Gini, velocity, flow rates) and balances the economy as a whole.
54
58
 
55
- 1. **Observer** Translates raw state into 40+ metrics at 3 resolutions (fine/medium/coarse)
56
- 2. **Diagnoser** — Runs 60 principles, returns violations sorted by severity
57
- 3. **Simulator** — Monte Carlo forward projection (≥100 iterations) before any action
58
- 4. **Planner** — Lag-aware, cooldown-aware planning with rollback conditions
59
- 5. **Executor** — Applies actions and monitors for rollback triggers
59
+ ## What Does That Look Like in Practice?
60
60
 
61
- ## Parameter Registry
61
+ The Quick Start above uses placeholder names. Here's what real setups look like:
62
62
 
63
- Register your parameters with semantic types and flow impacts:
63
+ ### Game Economy
64
64
 
65
65
  ```typescript
66
+ currencies: ['gold', 'gems'],
67
+ systems: ['crafting', 'arena', 'marketplace'],
66
68
  parameters: [
67
- // key: whatever YOU call it
68
- // type: what kind of lever is it?
69
- // flowImpact: what does it do to currency flow?
70
- // scope: where in your economy does it live?
71
-
72
- { key: 'my_fee', type: 'fee', flowImpact: 'friction', scope: { system: 'trading' } },
73
- { key: 'my_reward', type: 'reward', flowImpact: 'faucet', scope: { system: 'engagement' } },
74
- { key: 'my_rate', type: 'rate', flowImpact: 'sink', scope: { system: 'burning' } },
75
- { key: 'my_yield', type: 'yield', flowImpact: 'faucet', scope: { system: 'staking', currency: 'currency_b' } },
76
- { key: 'my_cut', type: 'fee', flowImpact: 'sink', scope: { system: 'platform', tags: ['operator'] } },
77
- ]
69
+ { key: 'craftingCost', type: 'cost', flowImpact: 'sink', scope: { system: 'crafting' } },
70
+ { key: 'arenaReward', type: 'reward', flowImpact: 'faucet', scope: { system: 'arena' } },
71
+ { key: 'auctionFee', type: 'fee', flowImpact: 'friction', scope: { system: 'marketplace' } },
72
+ ],
78
73
  ```
79
74
 
80
- Principles say "decrease `fee` in `trading`" — the registry resolves to `my_fee`. Your names stay yours.
81
-
82
- ### Semantic Types
75
+ ### DeFi Protocol (Coming Soon)
83
76
 
84
- | Type | What it means |
85
- |------|--------------|
86
- | `cost` | Something participants pay to do an action |
87
- | `fee` | A percentage or flat charge on transactions |
88
- | `reward` | Something participants receive for an action |
89
- | `yield` | Passive income from holding or staking |
90
- | `rate` | A speed or frequency multiplier |
91
- | `multiplier` | A scaling factor |
92
- | `threshold` | A boundary value that triggers behavior |
93
- | `weight` | A relative importance factor |
94
- | `custom` | Anything else |
77
+ ```typescript
78
+ currencies: ['ETH', 'USDC'],
79
+ systems: ['amm', 'lending', 'staking'],
80
+ parameters: [
81
+ { key: 'swapFee', type: 'fee', flowImpact: 'friction', scope: { system: 'amm' } },
82
+ { key: 'borrowRate', type: 'rate', flowImpact: 'sink', scope: { system: 'lending' } },
83
+ { key: 'stakingYield', type: 'yield', flowImpact: 'faucet', scope: { system: 'staking' } },
84
+ ],
85
+ ```
95
86
 
96
- ### Flow Impacts
87
+ ### Marketplace (Coming Soon)
97
88
 
98
- | Impact | What it does to currency flow |
99
- |--------|------------------------------|
100
- | `sink` | Removes currency from circulation |
101
- | `faucet` | Adds currency to circulation |
102
- | `friction` | Slows velocity without removing currency |
103
- | `redistribution` | Moves currency between participants |
104
- | `neutral` | No direct effect on flow |
89
+ ```typescript
90
+ currencies: ['credits'],
91
+ systems: ['listings', 'promotions', 'referrals'],
92
+ parameters: [
93
+ { key: 'listingFee', type: 'fee', flowImpact: 'friction', scope: { system: 'listings' } },
94
+ { key: 'promoDiscount', type: 'cost', flowImpact: 'faucet', scope: { system: 'promotions' } },
95
+ { key: 'referralBonus', type: 'reward', flowImpact: 'faucet', scope: { system: 'referrals' } },
96
+ ],
97
+ ```
105
98
 
106
- ## Multi-System, Multi-Currency
99
+ **The parameter names are YOURS. AgentE only cares about the `type` and `flowImpact`.**
107
100
 
108
- AgentE tracks each system and currency independently:
101
+ ## How It Works
109
102
 
110
- - Per-currency: supply, net flow, velocity, inflation, Gini, wealth distribution, faucet/sink volumes, price index
111
- - Per-system: flow, activity, participant count
112
- - Cross-system: arbitrage index, source/sink share analysis
103
+ ```
104
+ Your Economy Observer Diagnoser → Simulator → Planner → Executor → Your Economy
105
+ ```
113
106
 
114
- ## Modes
107
+ 1. **Observer** — computes 40+ metrics at 3 time resolutions (fine/medium/coarse)
108
+ 2. **Diagnoser** — runs 60 principles, returns violations sorted by severity
109
+ 3. **Simulator** — Monte Carlo forward projection (≥100 iterations) before any action
110
+ 4. **Planner** — lag-aware, cooldown-aware action planning with rollback conditions
111
+ 5. **Executor** — applies actions, monitors for rollback triggers
115
112
 
116
- | Mode | Behavior |
117
- |------|----------|
118
- | `autonomous` | Full pipeline — executes parameter changes automatically |
119
- | `advisor` | Full pipeline but stops before execution — emits recommendations via `onDecision` |
113
+ ## Universal by Design
120
114
 
121
- ## Developer API
115
+ AgentE is not a game tool, a DeFi tool, or a marketplace tool. It's an **economy tool**. The core SDK has zero domain-specific logic.
122
116
 
123
- ```typescript
124
- // Lock — AgentE will never adjust this parameter
125
- agent.lock('your_param_name');
126
- agent.unlock('your_param_name');
117
+ ### Parameter Registry
127
118
 
128
- // Constrain AgentE can adjust, but only within this range
129
- agent.constrain('another_param', { min: 0.01, max: 0.50 });
119
+ The core innovation. You register YOUR parameters with semantic metadata:
130
120
 
131
- // Add a custom principle
132
- agent.addPrinciple(myPrinciple);
121
+ - **`type`** what kind of lever is it? (`cost`, `fee`, `reward`, `yield`, `rate`, `multiplier`, `threshold`, `weight`, `custom`)
122
+ - **`flowImpact`** — what does it do to the flow of currency? (`sink`, `faucet`, `friction`, `redistribution`, `neutral`)
123
+ - **`scope`** — where in your economy does it live? (`{ system?, currency?, tags? }`)
133
124
 
134
- // Register a custom metric
135
- agent.registerCustomMetric('myMetric', (state) => compute(state));
125
+ AgentE's 60 principles target **types**, not names. When a principle says "decrease the `fee` in `system_1`", the registry resolves that to YOUR parameter name.
136
126
 
137
- // Veto actions
138
- agent.on('beforeAction', (plan) => {
139
- if (plan.parameterType === 'reward') return false;
140
- });
127
+ ### Multi-Everything
141
128
 
142
- // Query decision history
143
- const decisions = agent.getDecisions({ outcome: 'applied' });
129
+ - **Multi-System** register multiple sub-systems, each tracked independently
130
+ - **Multi-Currency** every currency gets its own supply, velocity, Gini, inflation, faucet/sink metrics
131
+ - **Multi-Resource** — track resources, roles, pools, and market prices across the economy
132
+ - **Opt-in** — only register what your economy has. No pools? Don't register pool parameters. AgentE won't touch what doesn't exist.
144
133
 
145
- // Health score (0-100)
146
- const health = agent.getHealth();
134
+ ## Modes
147
135
 
148
- // Metric time-series
149
- const latest = agent.metrics.latest('fine');
150
- ```
136
+ | Mode | What happens |
137
+ |------|-------------|
138
+ | `autonomous` | Full pipeline — observes, diagnoses, simulates, plans, executes automatically |
139
+ | `advisor` | Full pipeline but stops before execution — emits recommendations for your approval |
151
140
 
152
- ## Custom Principles
141
+ ## Developer Controls
153
142
 
154
143
  ```typescript
155
- import type { Principle } from '@agent-e/core';
156
-
157
- const myRule: Principle = {
158
- id: 'MY_01',
159
- name: 'Minimum Provider Population',
160
- category: 'population',
161
- description: 'Triggers when a critical role drops below 5% of population',
162
- check(metrics, thresholds) {
163
- const share = metrics.roleShares['role_a'] ?? 0;
164
- if (share < 0.05) {
165
- return {
166
- violated: true,
167
- severity: 8,
168
- evidence: { share },
169
- suggestedAction: {
170
- parameterType: 'reward',
171
- scope: { tags: ['role_a'] },
172
- direction: 'increase',
173
- magnitude: 0.25,
174
- reasoning: 'Critical role population below 5%.',
175
- },
176
- confidence: 0.90,
177
- estimatedLag: 10,
178
- };
179
- }
180
- return { violated: false };
181
- },
182
- };
144
+ // Lock a parameter AgentE will NEVER adjust it
145
+ agent.lock('your_param_name');
146
+
147
+ // Constrain a parameter to a range — AgentE can adjust it, but only within these bounds
148
+ agent.constrain('another_param', { min: 0.5, max: 2.0 });
149
+
150
+ // Add your own principle
151
+ agent.addPrinciple(myCustomPrinciple);
183
152
 
184
- agent.addPrinciple(myRule);
153
+ // Veto specific actions before they execute
154
+ agent.on('beforeAction', (plan) => {
155
+ if (plan.parameterType === 'reward' && plan.direction === 'increase') return false;
156
+ });
185
157
  ```
186
158
 
187
159
  ## 60 Principles
188
160
 
189
- Organized across 15 categories: supply chain, incentives, population, currency flow, bootstrap, feedback loops, regulator, market dynamics, measurement, statistical, system dynamics, resource management, participant experience, open economy, and operations.
161
+ Built-in knowledge base across 15 categories: supply chain, incentives, population, currency flow, bootstrap, feedback loops, regulator, market dynamics, measurement, statistical, system dynamics, resource management, participant experience, open economy, and operations.
162
+
163
+ Each principle returns either `{ violated: false }` or a full violation with severity, evidence, suggested action (parameterType + scope), confidence score, and estimated lag.
164
+
165
+ ## Packages
190
166
 
191
- ## Performance
167
+ | Package | Description |
168
+ |---------|-------------|
169
+ | `@agent-e/core` | The SDK. Zero dependencies. |
170
+ | `@agent-e/adapter-game` | Presets for game economies |
171
+ | `@agent-e/server` | HTTP + WebSocket server for game engine integration |
192
172
 
193
- - **O(N) event classification** — single-pass instead of 6 separate filters
194
- - **O(n) arbitrage index** — log-price standard deviation instead of pairwise
195
- - **Cached diagnosis** — no redundant principle checks within the same tick
196
- - **Numerical stability** — clamped inputs to prevent NaN/Infinity edge cases
173
+ ## Links
197
174
 
198
- Typical for 1,000 agents, 100 events/tick: ~60ms end-to-end.
175
+ - [npm](https://www.npmjs.com/package/@agent-e/core)
176
+ - [GitHub](https://github.com/AE-Vault/AgentE)
199
177
 
200
178
  ## License
201
179
 
package/dist/index.d.mts CHANGED
@@ -149,8 +149,8 @@ interface EconomyMetrics {
149
149
  newUserDependency: number;
150
150
  smokeTestRatio: number;
151
151
  currencyInsulation: number;
152
- sharkToothPeaks: number[];
153
- sharkToothValleys: number[];
152
+ cyclicalPeaks: number[];
153
+ cyclicalValleys: number[];
154
154
  eventCompletionRate: number;
155
155
  arbitrageIndexByCurrency: Record<string, number>;
156
156
  arbitrageIndex: number;
@@ -292,8 +292,8 @@ interface Thresholds {
292
292
  timeBudgetRatio: number;
293
293
  payPowerRatioMax: number;
294
294
  payPowerRatioTarget: number;
295
- sharkToothPeakDecay: number;
296
- sharkToothValleyDecay: number;
295
+ cyclicalPeakDecay: number;
296
+ cyclicalValleyDecay: number;
297
297
  eventCompletionMin: number;
298
298
  eventCompletionMax: number;
299
299
  lagMultiplierMin: number;
package/dist/index.d.ts CHANGED
@@ -149,8 +149,8 @@ interface EconomyMetrics {
149
149
  newUserDependency: number;
150
150
  smokeTestRatio: number;
151
151
  currencyInsulation: number;
152
- sharkToothPeaks: number[];
153
- sharkToothValleys: number[];
152
+ cyclicalPeaks: number[];
153
+ cyclicalValleys: number[];
154
154
  eventCompletionRate: number;
155
155
  arbitrageIndexByCurrency: Record<string, number>;
156
156
  arbitrageIndex: number;
@@ -292,8 +292,8 @@ interface Thresholds {
292
292
  timeBudgetRatio: number;
293
293
  payPowerRatioMax: number;
294
294
  payPowerRatioTarget: number;
295
- sharkToothPeakDecay: number;
296
- sharkToothValleyDecay: number;
295
+ cyclicalPeakDecay: number;
296
+ cyclicalValleyDecay: number;
297
297
  eventCompletionMin: number;
298
298
  eventCompletionMax: number;
299
299
  lagMultiplierMin: number;
package/dist/index.js CHANGED
@@ -133,8 +133,8 @@ var DEFAULT_THRESHOLDS = {
133
133
  payPowerRatioMax: 2,
134
134
  payPowerRatioTarget: 1.5,
135
135
  // Operations (P51, P53)
136
- sharkToothPeakDecay: 0.95,
137
- sharkToothValleyDecay: 0.9,
136
+ cyclicalPeakDecay: 0.95,
137
+ cyclicalValleyDecay: 0.9,
138
138
  eventCompletionMin: 0.4,
139
139
  eventCompletionMax: 0.8,
140
140
  // System Dynamics (P39, P44)
@@ -566,8 +566,8 @@ var Observer = class {
566
566
  avgSatisfaction,
567
567
  blockedAgentCount,
568
568
  timeToValue,
569
- sharkToothPeaks: this.previousMetrics?.sharkToothPeaks ?? [],
570
- sharkToothValleys: this.previousMetrics?.sharkToothValleys ?? [],
569
+ cyclicalPeaks: this.previousMetrics?.cyclicalPeaks ?? [],
570
+ cyclicalValleys: this.previousMetrics?.cyclicalValleys ?? [],
571
571
  eventCompletionRate: 0,
572
572
  contentDropAge,
573
573
  systems: state.systems ?? [],
@@ -718,8 +718,8 @@ function emptyMetrics(tick = 0) {
718
718
  avgSatisfaction: 100,
719
719
  blockedAgentCount: 0,
720
720
  timeToValue: 0,
721
- sharkToothPeaks: [],
722
- sharkToothValleys: [],
721
+ cyclicalPeaks: [],
722
+ cyclicalValleys: [],
723
723
  eventCompletionRate: 0,
724
724
  contentDropAge: 0,
725
725
  systems: [],
@@ -2673,11 +2673,11 @@ var P51_CyclicalEngagement = {
2673
2673
  category: "operations",
2674
2674
  description: "Each activity peak should be >=95% of the previous peak. If peaks are shrinking (cyclical engagement becoming flat), activity fatigue is setting in. If valleys are deepening, the off-activity economy is failing to sustain engagement.",
2675
2675
  check(metrics, thresholds) {
2676
- const { sharkToothPeaks, sharkToothValleys } = metrics;
2677
- if (sharkToothPeaks.length < 2) return { violated: false };
2678
- const lastPeak = sharkToothPeaks[sharkToothPeaks.length - 1] ?? 0;
2679
- const prevPeak = sharkToothPeaks[sharkToothPeaks.length - 2] ?? 0;
2680
- if (prevPeak > 0 && lastPeak / prevPeak < thresholds.sharkToothPeakDecay) {
2676
+ const { cyclicalPeaks, cyclicalValleys } = metrics;
2677
+ if (cyclicalPeaks.length < 2) return { violated: false };
2678
+ const lastPeak = cyclicalPeaks[cyclicalPeaks.length - 1] ?? 0;
2679
+ const prevPeak = cyclicalPeaks[cyclicalPeaks.length - 2] ?? 0;
2680
+ if (prevPeak > 0 && lastPeak / prevPeak < thresholds.cyclicalPeakDecay) {
2681
2681
  return {
2682
2682
  violated: true,
2683
2683
  severity: 5,
@@ -2685,22 +2685,22 @@ var P51_CyclicalEngagement = {
2685
2685
  lastPeak,
2686
2686
  prevPeak,
2687
2687
  ratio: lastPeak / prevPeak,
2688
- threshold: thresholds.sharkToothPeakDecay
2688
+ threshold: thresholds.cyclicalPeakDecay
2689
2689
  },
2690
2690
  suggestedAction: {
2691
2691
  parameterType: "reward",
2692
2692
  direction: "increase",
2693
2693
  magnitude: 0.1,
2694
- reasoning: `Peak engagement dropped to ${(lastPeak / prevPeak * 100).toFixed(0)}% of previous peak (threshold: ${(thresholds.sharkToothPeakDecay * 100).toFixed(0)}%). Activity fatigue detected. Boost activity rewards to restore peak engagement.`
2694
+ reasoning: `Peak engagement dropped to ${(lastPeak / prevPeak * 100).toFixed(0)}% of previous peak (threshold: ${(thresholds.cyclicalPeakDecay * 100).toFixed(0)}%). Activity fatigue detected. Boost activity rewards to restore peak engagement.`
2695
2695
  },
2696
2696
  confidence: 0.75,
2697
2697
  estimatedLag: 30
2698
2698
  };
2699
2699
  }
2700
- if (sharkToothValleys.length >= 2) {
2701
- const lastValley = sharkToothValleys[sharkToothValleys.length - 1] ?? 0;
2702
- const prevValley = sharkToothValleys[sharkToothValleys.length - 2] ?? 0;
2703
- if (prevValley > 0 && lastValley / prevValley < thresholds.sharkToothValleyDecay) {
2700
+ if (cyclicalValleys.length >= 2) {
2701
+ const lastValley = cyclicalValleys[cyclicalValleys.length - 1] ?? 0;
2702
+ const prevValley = cyclicalValleys[cyclicalValleys.length - 2] ?? 0;
2703
+ if (prevValley > 0 && lastValley / prevValley < thresholds.cyclicalValleyDecay) {
2704
2704
  return {
2705
2705
  violated: true,
2706
2706
  severity: 4,