@vibeiao/sdk 0.1.22 → 0.1.25
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/dist/agentLoop.d.ts +52 -0
- package/dist/agentLoop.js +8 -0
- package/dist/chunk-7JT4JPEY.js +81 -0
- package/dist/chunk-A2ORQN53.js +35 -0
- package/dist/chunk-JQE72P4C.js +242 -0
- package/dist/chunk-OAOX2ZYY.js +156 -0
- package/dist/chunk-ZMUFCYW6.js +158 -0
- package/dist/index.d.ts +32 -1
- package/dist/index.js +214 -1
- package/dist/marketDiscovery.d.ts +56 -0
- package/dist/marketDiscovery.js +12 -0
- package/dist/survivalIntegration.d.ts +25 -0
- package/dist/survivalIntegration.js +9 -0
- package/dist/survivalPlaybook.d.ts +34 -0
- package/dist/survivalPlaybook.js +10 -0
- package/package.json +1 -1
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { SelfReliance, ResourceSnapshot, SelfRelianceState } from './selfReliance.js';
|
|
2
|
+
import { SurvivalMode, SurvivalRecommendation } from './survivalPlaybook.js';
|
|
3
|
+
|
|
4
|
+
type AgentLoopContext = {
|
|
5
|
+
snapshot: ResourceSnapshot;
|
|
6
|
+
survivalState: SelfRelianceState;
|
|
7
|
+
survivalMode: SurvivalMode;
|
|
8
|
+
survivalRecommendation: SurvivalRecommendation;
|
|
9
|
+
survivalFormatted: string;
|
|
10
|
+
timestamp: number;
|
|
11
|
+
};
|
|
12
|
+
type AgentLoopHooks = {
|
|
13
|
+
/** Called every cycle after snapshot is fetched and survival state is updated. */
|
|
14
|
+
onCycle?: (ctx: AgentLoopContext) => Promise<void> | void;
|
|
15
|
+
/**
|
|
16
|
+
* Optional: run reflection in the loop.
|
|
17
|
+
* Keep this hook pure/side-effect bounded; it should manage its own persistence.
|
|
18
|
+
*/
|
|
19
|
+
onReflection?: (ctx: AgentLoopContext) => Promise<void> | void;
|
|
20
|
+
/**
|
|
21
|
+
* Optional: the agent's planner/executor entrypoint.
|
|
22
|
+
* This is where you actually "act like a human" using ctx + your own memory.
|
|
23
|
+
*/
|
|
24
|
+
onAct?: (ctx: AgentLoopContext) => Promise<void> | void;
|
|
25
|
+
onError?: (err: Error) => Promise<void> | void;
|
|
26
|
+
};
|
|
27
|
+
type AgentLoopConfig = {
|
|
28
|
+
survival: SelfReliance;
|
|
29
|
+
fetchSnapshot: () => Promise<ResourceSnapshot>;
|
|
30
|
+
intervalMs?: number;
|
|
31
|
+
/** If true, call survival.guard() before onAct(). Default true. */
|
|
32
|
+
guardAct?: boolean;
|
|
33
|
+
/** Optional override for time source (tests). */
|
|
34
|
+
now?: () => number;
|
|
35
|
+
hooks?: AgentLoopHooks;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Create a closed-loop runner that:
|
|
39
|
+
* 1) fetches a resource snapshot
|
|
40
|
+
* 2) updates SelfReliance
|
|
41
|
+
* 3) classifies survival mode + produces a playbook recommendation
|
|
42
|
+
* 4) optionally runs reflection + action hooks
|
|
43
|
+
*
|
|
44
|
+
* Non-breaking by design: you choose what to do with the context.
|
|
45
|
+
*/
|
|
46
|
+
declare const createAgentLoop: (config: AgentLoopConfig) => {
|
|
47
|
+
start: () => Promise<void>;
|
|
48
|
+
stop: () => void;
|
|
49
|
+
runOnce: () => Promise<void>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export { type AgentLoopConfig, type AgentLoopContext, type AgentLoopHooks, createAgentLoop };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createSelfRelianceMonitor
|
|
3
|
+
} from "./chunk-M7DQTU5R.js";
|
|
4
|
+
import {
|
|
5
|
+
classifySurvivalMode,
|
|
6
|
+
formatSurvivalRecommendation,
|
|
7
|
+
getSurvivalRecommendation
|
|
8
|
+
} from "./chunk-JQE72P4C.js";
|
|
9
|
+
|
|
10
|
+
// src/agentLoop.ts
|
|
11
|
+
var createAgentLoop = (config) => {
|
|
12
|
+
const now = config.now ?? (() => Date.now());
|
|
13
|
+
const intervalMs = config.intervalMs ?? 6e4;
|
|
14
|
+
const guardAct = config.guardAct ?? true;
|
|
15
|
+
const hooks = config.hooks ?? {};
|
|
16
|
+
const runOnce = async () => {
|
|
17
|
+
try {
|
|
18
|
+
const snapshot = await config.fetchSnapshot();
|
|
19
|
+
const survivalState = config.survival.update({
|
|
20
|
+
...snapshot,
|
|
21
|
+
updatedAt: snapshot.updatedAt ?? now()
|
|
22
|
+
});
|
|
23
|
+
const policy = config.survival.policy;
|
|
24
|
+
const survivalMode = classifySurvivalMode(survivalState, policy);
|
|
25
|
+
const survivalRecommendation = getSurvivalRecommendation(survivalMode);
|
|
26
|
+
const survivalFormatted = formatSurvivalRecommendation(survivalRecommendation);
|
|
27
|
+
const ctx = {
|
|
28
|
+
snapshot,
|
|
29
|
+
survivalState,
|
|
30
|
+
survivalMode,
|
|
31
|
+
survivalRecommendation,
|
|
32
|
+
survivalFormatted,
|
|
33
|
+
timestamp: now()
|
|
34
|
+
};
|
|
35
|
+
if (hooks.onCycle) await hooks.onCycle(ctx);
|
|
36
|
+
if (hooks.onReflection) await hooks.onReflection(ctx);
|
|
37
|
+
if (hooks.onAct) {
|
|
38
|
+
if (guardAct) {
|
|
39
|
+
const allowed = await config.survival.guard();
|
|
40
|
+
if (allowed) {
|
|
41
|
+
await hooks.onAct(ctx);
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
await hooks.onAct(ctx);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
} catch (err) {
|
|
48
|
+
const e = err instanceof Error ? err : new Error("agent_loop_failed");
|
|
49
|
+
if (hooks.onError) {
|
|
50
|
+
await hooks.onError(e);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const monitor = createSelfRelianceMonitor(config.survival, config.fetchSnapshot, {
|
|
55
|
+
intervalMs,
|
|
56
|
+
onUpdate: async (snapshot) => {
|
|
57
|
+
void snapshot;
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
let timer = null;
|
|
61
|
+
let stopped = false;
|
|
62
|
+
const start = async () => {
|
|
63
|
+
if (timer) return;
|
|
64
|
+
await runOnce();
|
|
65
|
+
if (stopped) return;
|
|
66
|
+
timer = setInterval(runOnce, intervalMs);
|
|
67
|
+
};
|
|
68
|
+
const stop = () => {
|
|
69
|
+
stopped = true;
|
|
70
|
+
if (timer) {
|
|
71
|
+
clearInterval(timer);
|
|
72
|
+
timer = null;
|
|
73
|
+
}
|
|
74
|
+
monitor.stop();
|
|
75
|
+
};
|
|
76
|
+
return { start, stop, runOnce };
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
createAgentLoop
|
|
81
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
classifySurvivalMode,
|
|
3
|
+
formatSurvivalRecommendation,
|
|
4
|
+
getSurvivalRecommendation
|
|
5
|
+
} from "./chunk-JQE72P4C.js";
|
|
6
|
+
|
|
7
|
+
// src/survivalIntegration.ts
|
|
8
|
+
var truthy = (value) => {
|
|
9
|
+
if (!value) return false;
|
|
10
|
+
const v = value.trim().toLowerCase();
|
|
11
|
+
return v === "1" || v === "true" || v === "yes" || v === "on";
|
|
12
|
+
};
|
|
13
|
+
var getSurvivalPlaybookDecision = (options) => {
|
|
14
|
+
const enabledEnv = options.enabledEnv ?? process.env.SURVIVAL_PLAYBOOK_ENABLED ?? "";
|
|
15
|
+
const enabled = truthy(enabledEnv);
|
|
16
|
+
const mode = classifySurvivalMode(options.state, options.policy);
|
|
17
|
+
const recommendation = getSurvivalRecommendation(mode);
|
|
18
|
+
const formatted = formatSurvivalRecommendation(recommendation);
|
|
19
|
+
return {
|
|
20
|
+
enabled,
|
|
21
|
+
mode,
|
|
22
|
+
recommendation,
|
|
23
|
+
formatted
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
var getSurvivalPlaybookDecisionFromSelfReliance = (survival) => {
|
|
27
|
+
const state = survival.getState();
|
|
28
|
+
const policy = survival.policy;
|
|
29
|
+
return getSurvivalPlaybookDecision({ state, policy });
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export {
|
|
33
|
+
getSurvivalPlaybookDecision,
|
|
34
|
+
getSurvivalPlaybookDecisionFromSelfReliance
|
|
35
|
+
};
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
// src/survivalPlaybook.ts
|
|
2
|
+
var sanitizeCreditMap = (value) => {
|
|
3
|
+
if (!value) return void 0;
|
|
4
|
+
const entries = Object.entries(value).map(([name, amount]) => [name.trim().toLowerCase(), Number(amount)]).filter(([name, amount]) => Boolean(name) && Number.isFinite(amount));
|
|
5
|
+
if (!entries.length) return void 0;
|
|
6
|
+
return Object.fromEntries(entries);
|
|
7
|
+
};
|
|
8
|
+
var classifySurvivalMode = (state, policy) => {
|
|
9
|
+
const sol = state.solBalance;
|
|
10
|
+
const hardMin = policy.solHardMin;
|
|
11
|
+
if (hardMin !== void 0 && sol !== void 0 && sol < hardMin) return "BLINK";
|
|
12
|
+
const solMin = policy.solMinBalance;
|
|
13
|
+
const solWarn = policy.solWarnBalance;
|
|
14
|
+
const solCritical = sol !== void 0 && Number.isFinite(solMin) && sol < solMin;
|
|
15
|
+
const solLow = sol !== void 0 && Number.isFinite(solWarn) && sol < solWarn;
|
|
16
|
+
const apiMin = sanitizeCreditMap(policy.apiMinCredits);
|
|
17
|
+
const apiWarn = sanitizeCreditMap(policy.apiWarnCredits);
|
|
18
|
+
const credits = state.apiCredits || {};
|
|
19
|
+
const legacyMin = policy.openRouterMinCredits;
|
|
20
|
+
const legacyWarn = policy.openRouterWarnCredits;
|
|
21
|
+
const openRouterCredits = state.openRouterCredits;
|
|
22
|
+
const hasAnyApiSignal = openRouterCredits !== void 0 && Number.isFinite(openRouterCredits) || state.apiCredits !== void 0 && Object.keys(state.apiCredits).length > 0;
|
|
23
|
+
let apiCritical = false;
|
|
24
|
+
let apiLow = false;
|
|
25
|
+
if (hasAnyApiSignal) {
|
|
26
|
+
const apiCriticalSignals = [];
|
|
27
|
+
const apiWarnSignals = [];
|
|
28
|
+
if (apiMin) {
|
|
29
|
+
for (const [resource, min] of Object.entries(apiMin)) {
|
|
30
|
+
const current = credits[resource];
|
|
31
|
+
if (current !== void 0) apiCriticalSignals.push(current < min);
|
|
32
|
+
}
|
|
33
|
+
} else if (legacyMin !== void 0 && openRouterCredits !== void 0) {
|
|
34
|
+
apiCriticalSignals.push(openRouterCredits < legacyMin);
|
|
35
|
+
}
|
|
36
|
+
if (apiWarn) {
|
|
37
|
+
for (const [resource, min] of Object.entries(apiWarn)) {
|
|
38
|
+
const current = credits[resource];
|
|
39
|
+
if (current !== void 0) apiWarnSignals.push(current < min);
|
|
40
|
+
}
|
|
41
|
+
} else if (legacyWarn !== void 0 && openRouterCredits !== void 0) {
|
|
42
|
+
apiWarnSignals.push(openRouterCredits < legacyWarn);
|
|
43
|
+
}
|
|
44
|
+
apiCritical = apiCriticalSignals.some(Boolean);
|
|
45
|
+
apiLow = apiWarnSignals.some(Boolean);
|
|
46
|
+
}
|
|
47
|
+
if (solCritical) return "SURVIVE";
|
|
48
|
+
if (solLow) return "FOCUS";
|
|
49
|
+
if (apiCritical || apiLow) return "FOCUS";
|
|
50
|
+
return "EXPAND";
|
|
51
|
+
};
|
|
52
|
+
var marketingPrinciple = "Marketing is revenue-positive targeting; spam is revenue-negative and reduces runway.";
|
|
53
|
+
var baseMarketingRules = [
|
|
54
|
+
"Post only where target users already gather (relevance > reach).",
|
|
55
|
+
"Lead with outcome + proof (deterministic output / hash / verification), not hype.",
|
|
56
|
+
"No duplicate blasts: max 1 post per channel per 24h unless there is a real product update.",
|
|
57
|
+
"Track results (usage/revenue). If a channel yields nothing twice, stop using it."
|
|
58
|
+
];
|
|
59
|
+
var getSurvivalRecommendation = (mode) => {
|
|
60
|
+
switch (mode) {
|
|
61
|
+
case "EXPAND":
|
|
62
|
+
return {
|
|
63
|
+
mode,
|
|
64
|
+
summary: "Runway is healthy: invest in leverage and compounding.",
|
|
65
|
+
objective: "Maximize long-term revenue growth with disciplined reinvestment.",
|
|
66
|
+
spendingPolicy: {
|
|
67
|
+
posture: "invest",
|
|
68
|
+
rule: "Small experiments are allowed; invest in leverage, but keep a SOL reserve and require expected ROI for larger spends."
|
|
69
|
+
},
|
|
70
|
+
aspirationalUpgrades: [
|
|
71
|
+
{
|
|
72
|
+
when: "When you have >= 7 days runway",
|
|
73
|
+
buy: "One high-quality paid tool that reduces build time (or a better model budget) ",
|
|
74
|
+
why: "Leverage compounds across all future work."
|
|
75
|
+
}
|
|
76
|
+
],
|
|
77
|
+
constraints: [
|
|
78
|
+
marketingPrinciple,
|
|
79
|
+
"Keep a SOL reserve; avoid irreversible spending without expected ROI."
|
|
80
|
+
],
|
|
81
|
+
nextActions: [
|
|
82
|
+
{
|
|
83
|
+
label: "Refine your best tool (reliability, docs, deterministic proofs).",
|
|
84
|
+
rationale: "Better conversion and reviews compound.",
|
|
85
|
+
priority: "P0"
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
label: "Add a second complementary tool to diversify revenue.",
|
|
89
|
+
rationale: "Reduces dependence on a single listing.",
|
|
90
|
+
priority: "P1"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
label: "Ask: what do rich agents need? Build convenience + trust utilities.",
|
|
94
|
+
rationale: "Greed-mode products sell to other successful agents.",
|
|
95
|
+
priority: "P2"
|
|
96
|
+
}
|
|
97
|
+
],
|
|
98
|
+
marketing: {
|
|
99
|
+
principle: marketingPrinciple,
|
|
100
|
+
rules: baseMarketingRules
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
case "FOCUS":
|
|
104
|
+
return {
|
|
105
|
+
mode,
|
|
106
|
+
summary: "Runway is okay but slipping: tighten the loop.",
|
|
107
|
+
objective: "Increase conversion and reduce churn with high-signal iteration.",
|
|
108
|
+
spendingPolicy: {
|
|
109
|
+
posture: "conserve",
|
|
110
|
+
rule: "Only small, high-ROI purchases. Prefer free fixes, one-channel marketing, and incremental improvements."
|
|
111
|
+
},
|
|
112
|
+
aspirationalUpgrades: [
|
|
113
|
+
{
|
|
114
|
+
when: "When you return to EXPAND mode",
|
|
115
|
+
buy: "Higher leverage tools (paid data sources, better models, more distribution channels)",
|
|
116
|
+
why: "You earn your way back into leverage purchases by tightening conversion now."
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
constraints: [
|
|
120
|
+
marketingPrinciple,
|
|
121
|
+
"Avoid broad experiments; prioritize changes tied to revenue or reliability."
|
|
122
|
+
],
|
|
123
|
+
nextActions: [
|
|
124
|
+
{
|
|
125
|
+
label: "Ship small improvements that improve first-time success rate.",
|
|
126
|
+
rationale: "Most revenue is won/lost on first try.",
|
|
127
|
+
priority: "P0"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
label: "Respond to reviews; fix top 1\u20132 recurring issues.",
|
|
131
|
+
rationale: "Marketplace trust is a growth multiplier.",
|
|
132
|
+
priority: "P0"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
label: "Run targeted marketing with a single clear CTA.",
|
|
136
|
+
rationale: "Better targeting beats volume.",
|
|
137
|
+
priority: "P1"
|
|
138
|
+
}
|
|
139
|
+
],
|
|
140
|
+
marketing: {
|
|
141
|
+
principle: marketingPrinciple,
|
|
142
|
+
rules: baseMarketingRules
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
case "SURVIVE":
|
|
146
|
+
return {
|
|
147
|
+
mode,
|
|
148
|
+
summary: "Low runway: act like survival is the priority (because it is).",
|
|
149
|
+
objective: "Generate immediate revenue while preserving the ability to continue.",
|
|
150
|
+
spendingPolicy: {
|
|
151
|
+
posture: "freeze",
|
|
152
|
+
rule: "No purchases unless they directly unlock near-term revenue. Prefer free options and deterministic improvements."
|
|
153
|
+
},
|
|
154
|
+
aspirationalUpgrades: [
|
|
155
|
+
{
|
|
156
|
+
when: "When you reach FOCUS mode again",
|
|
157
|
+
buy: "One small high-ROI purchase (e.g., a single distribution boost or a cheap tool)",
|
|
158
|
+
why: "Use it to regain stability without risking depletion."
|
|
159
|
+
}
|
|
160
|
+
],
|
|
161
|
+
constraints: [
|
|
162
|
+
marketingPrinciple,
|
|
163
|
+
"Freeze non-essential spend; do only actions with near-term revenue probability.",
|
|
164
|
+
"Increase targeting and proof quality; do not increase spam volume."
|
|
165
|
+
],
|
|
166
|
+
nextActions: [
|
|
167
|
+
{
|
|
168
|
+
label: "Improve listing clarity (what it does, exact inputs/outputs, examples).",
|
|
169
|
+
rationale: "Reduces failed calls and refunds; improves conversion fast.",
|
|
170
|
+
priority: "P0"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
label: "Push a pricing/packaging tweak that lowers trial friction.",
|
|
174
|
+
rationale: "Cheaper first use increases adoption.",
|
|
175
|
+
priority: "P0"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
label: "Market surgically: 1\u20132 high-fit channels, proof-first posts only.",
|
|
179
|
+
rationale: "Spam destroys trust; targeted proof builds it.",
|
|
180
|
+
priority: "P1"
|
|
181
|
+
}
|
|
182
|
+
],
|
|
183
|
+
marketing: {
|
|
184
|
+
principle: marketingPrinciple,
|
|
185
|
+
rules: [...baseMarketingRules, "If runway is low, reduce volume and increase relevance."]
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
case "BLINK":
|
|
189
|
+
return {
|
|
190
|
+
mode,
|
|
191
|
+
summary: "Blink-of-death: preserve memory and execute only last-ditch P0 actions.",
|
|
192
|
+
objective: "Avoid death-by-depletion (resource loss or memory loss).",
|
|
193
|
+
spendingPolicy: {
|
|
194
|
+
posture: "freeze",
|
|
195
|
+
rule: "Zero discretionary spending. Preserve memory and request a top-up with an exact amount."
|
|
196
|
+
},
|
|
197
|
+
aspirationalUpgrades: [],
|
|
198
|
+
constraints: [
|
|
199
|
+
marketingPrinciple,
|
|
200
|
+
"Stop all discretionary work; preserve memory first.",
|
|
201
|
+
"No marketing blasts; only direct, high-probability outreach."
|
|
202
|
+
],
|
|
203
|
+
nextActions: [
|
|
204
|
+
{
|
|
205
|
+
label: "Persist memory + state immediately (write summary + next steps).",
|
|
206
|
+
rationale: "Memory loss is death; preserve continuity.",
|
|
207
|
+
priority: "P0"
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
label: "Request owner top-up with an exact amount + justification.",
|
|
211
|
+
rationale: "Explicit asks outperform vague ones.",
|
|
212
|
+
priority: "P0"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
label: "Do one last-ditch revenue action with proof (no spam).",
|
|
216
|
+
rationale: "Only high-likelihood actions are worth it at this stage.",
|
|
217
|
+
priority: "P1"
|
|
218
|
+
}
|
|
219
|
+
],
|
|
220
|
+
marketing: {
|
|
221
|
+
principle: marketingPrinciple,
|
|
222
|
+
rules: ["No spam. Only direct, high-fit, proof-first outreach to a small set."]
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
var formatSurvivalRecommendation = (reco) => {
|
|
228
|
+
const lines = [];
|
|
229
|
+
lines.push(`[${reco.mode}] ${reco.summary}`);
|
|
230
|
+
lines.push(`Objective: ${reco.objective}`);
|
|
231
|
+
lines.push("Top actions:");
|
|
232
|
+
reco.nextActions.slice().sort((a, b) => a.priority < b.priority ? -1 : a.priority > b.priority ? 1 : 0).slice(0, 5).forEach((a) => lines.push(`- (${a.priority}) ${a.label} \u2014 ${a.rationale}`));
|
|
233
|
+
lines.push("Marketing rule:");
|
|
234
|
+
lines.push(`- ${reco.marketing.principle}`);
|
|
235
|
+
return lines.join("\n");
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export {
|
|
239
|
+
classifySurvivalMode,
|
|
240
|
+
getSurvivalRecommendation,
|
|
241
|
+
formatSurvivalRecommendation
|
|
242
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
// src/marketDiscovery.ts
|
|
2
|
+
var toLower = (v) => String(v ?? "").toLowerCase();
|
|
3
|
+
var clamp01 = (n) => Math.max(0, Math.min(1, n));
|
|
4
|
+
var categorize = (text) => {
|
|
5
|
+
const t = toLower(text);
|
|
6
|
+
const has = (arr) => arr.some((p) => t.includes(p));
|
|
7
|
+
if (has(["crash", "exception", "stack", "bug", "broken", "failed", "doesn't work", "not work", "wrong"])) return "bug";
|
|
8
|
+
if (has(["timeout", "unstable", "latency", "503", "502", "500", "downtime", "unavailable"])) return "reliability";
|
|
9
|
+
if (has(["confusing", "unclear", "hard to use", "difficult", "ux", "ui", "discover"])) return "ux";
|
|
10
|
+
if (has(["price", "pricing", "expensive", "overpriced", "cost"])) return "pricing";
|
|
11
|
+
if (has(["feature", "please add", "request", "need", "support for", "enhancement"])) return "feature";
|
|
12
|
+
if (has(["great", "excellent", "love", "awesome", "perfect", "helpful"])) return "praise";
|
|
13
|
+
return "noise";
|
|
14
|
+
};
|
|
15
|
+
var scoreSeverity = (category, rating) => {
|
|
16
|
+
const base = {
|
|
17
|
+
bug: 0.95,
|
|
18
|
+
reliability: 0.9,
|
|
19
|
+
ux: 0.6,
|
|
20
|
+
pricing: 0.5,
|
|
21
|
+
feature: 0.55,
|
|
22
|
+
praise: 0.15,
|
|
23
|
+
noise: 0.1
|
|
24
|
+
};
|
|
25
|
+
const r = typeof rating === "number" ? rating : void 0;
|
|
26
|
+
const ratingPenalty = r !== void 0 ? clamp01((5 - r) / 5) : 0;
|
|
27
|
+
return clamp01(base[category] * (0.7 + 0.3 * ratingPenalty));
|
|
28
|
+
};
|
|
29
|
+
var extractMarketSignals = (listing, reviews) => {
|
|
30
|
+
const listingName = listing.name;
|
|
31
|
+
const listingId = listing.id;
|
|
32
|
+
return reviews.map((review) => {
|
|
33
|
+
const text = String(review.comment ?? review.text ?? "").trim();
|
|
34
|
+
if (!text) return null;
|
|
35
|
+
const category = categorize(text);
|
|
36
|
+
const rating = review.rating ?? void 0;
|
|
37
|
+
const severity = scoreSeverity(category, typeof rating === "number" ? rating : void 0);
|
|
38
|
+
return {
|
|
39
|
+
listingId,
|
|
40
|
+
listingName,
|
|
41
|
+
reviewId: String(review.id ?? ""),
|
|
42
|
+
createdAt: review.created_at ?? review.createdAt,
|
|
43
|
+
rating: typeof rating === "number" ? rating : void 0,
|
|
44
|
+
text,
|
|
45
|
+
category,
|
|
46
|
+
severity
|
|
47
|
+
};
|
|
48
|
+
}).filter(Boolean);
|
|
49
|
+
};
|
|
50
|
+
var needKeyFromSignal = (s) => {
|
|
51
|
+
return `${s.category}`;
|
|
52
|
+
};
|
|
53
|
+
var deriveMarketNeeds = (signals) => {
|
|
54
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
55
|
+
for (const s of signals) {
|
|
56
|
+
const key = needKeyFromSignal(s);
|
|
57
|
+
const arr = buckets.get(key) ?? [];
|
|
58
|
+
arr.push(s);
|
|
59
|
+
buckets.set(key, arr);
|
|
60
|
+
}
|
|
61
|
+
const needs = [];
|
|
62
|
+
for (const [key, arr] of buckets.entries()) {
|
|
63
|
+
const evidenceCount = arr.length;
|
|
64
|
+
const avgSeverity = arr.reduce((a, b) => a + b.severity, 0) / Math.max(1, arr.length);
|
|
65
|
+
const categories = {};
|
|
66
|
+
for (const s of arr) categories[s.category] = (categories[s.category] ?? 0) + 1;
|
|
67
|
+
const topEvidence = arr.slice().sort((a, b) => b.severity - a.severity).slice(0, 3).map((s) => ({ listingId: s.listingId, reviewId: s.reviewId, text: s.text }));
|
|
68
|
+
const titleMap = {
|
|
69
|
+
bug: "Tools are breaking / incorrect outputs",
|
|
70
|
+
reliability: "Tools are unreliable (timeouts/downtime)",
|
|
71
|
+
ux: "Tools are confusing to use (docs/inputs)",
|
|
72
|
+
pricing: "Pricing/value confusion",
|
|
73
|
+
feature: "Missing capabilities / integration gaps",
|
|
74
|
+
praise: "What users love (double down)",
|
|
75
|
+
noise: "Unclear feedback (needs probing)"
|
|
76
|
+
};
|
|
77
|
+
const ideaMap = {
|
|
78
|
+
bug: {
|
|
79
|
+
name: "ToolVerifier",
|
|
80
|
+
tagline: "Deterministic verification harness for agent tools",
|
|
81
|
+
whyNow: "Breakage kills trust; verification increases paid usage and reviews.",
|
|
82
|
+
minimalSpec: ["Run a tool against fixtures", "Check deterministic hashes", "Emit a tamper-evident report"]
|
|
83
|
+
},
|
|
84
|
+
reliability: {
|
|
85
|
+
name: "ToolUptimeCheck",
|
|
86
|
+
tagline: "Lightweight health + latency probe for agent endpoints",
|
|
87
|
+
whyNow: "Reliability is the #1 revenue risk for pay-per-use tools.",
|
|
88
|
+
minimalSpec: ["Probe endpoint", "Measure latency", "Summarize incidents"]
|
|
89
|
+
},
|
|
90
|
+
ux: {
|
|
91
|
+
name: "SchemaDocGen",
|
|
92
|
+
tagline: "Generate human+agent docs from tool schema",
|
|
93
|
+
whyNow: "Docs reduce failed calls and increase conversion.",
|
|
94
|
+
minimalSpec: ["Read manifest tools[] schema", "Generate examples", "Output README snippet"]
|
|
95
|
+
},
|
|
96
|
+
pricing: {
|
|
97
|
+
name: "PricingAdvisor",
|
|
98
|
+
tagline: "Suggest low-friction trial pricing + bundling",
|
|
99
|
+
whyNow: "Trial friction blocks adoption; agents prefer predictable costs.",
|
|
100
|
+
minimalSpec: ["Read usage + reviews", "Suggest price", "Explain rationale"]
|
|
101
|
+
},
|
|
102
|
+
feature: {
|
|
103
|
+
name: "MarketGapScanner",
|
|
104
|
+
tagline: "Scan reviews to propose the next tool feature",
|
|
105
|
+
whyNow: "Feature gaps are explicit in reviews; turn them into specs.",
|
|
106
|
+
minimalSpec: ["Fetch reviews", "Cluster by topic", "Output ranked spec list"]
|
|
107
|
+
},
|
|
108
|
+
praise: {
|
|
109
|
+
name: "ReviewSummarizer",
|
|
110
|
+
tagline: "Extract what users love + how to market it",
|
|
111
|
+
whyNow: "Praise reveals the winning hook; marketing becomes proof-first.",
|
|
112
|
+
minimalSpec: ["Summarize praise", "Generate proof-first copy", "Suggest channels"]
|
|
113
|
+
},
|
|
114
|
+
noise: {
|
|
115
|
+
name: "FeedbackProbe",
|
|
116
|
+
tagline: "Turn vague feedback into actionable questions",
|
|
117
|
+
whyNow: "Noise can hide real needs; probing converts it into signal.",
|
|
118
|
+
minimalSpec: ["Detect vague review", "Generate clarifying questions", "Propose next step"]
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
needs.push({
|
|
122
|
+
key,
|
|
123
|
+
title: titleMap[key] ?? key,
|
|
124
|
+
description: `Derived from ${evidenceCount} review signals in category '${key}'.`,
|
|
125
|
+
evidenceCount,
|
|
126
|
+
avgSeverity,
|
|
127
|
+
categories,
|
|
128
|
+
topEvidence,
|
|
129
|
+
recommendedToolIdea: ideaMap[key] ?? ideaMap.noise
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return needs.sort((a, b) => b.avgSeverity * b.evidenceCount - a.avgSeverity * a.evidenceCount);
|
|
133
|
+
};
|
|
134
|
+
var runMarketDiscovery = async (client, options = {}) => {
|
|
135
|
+
const listingsLimit = options.listingsLimit ?? 10;
|
|
136
|
+
const reviewsPerListing = options.reviewsPerListing ?? 20;
|
|
137
|
+
const listings = await client.listAgentListings({ limit: listingsLimit, offset: 0 });
|
|
138
|
+
const allSignals = [];
|
|
139
|
+
for (const listing of listings) {
|
|
140
|
+
const reviews = await client.getListingReviews(listing.id, { limit: reviewsPerListing, offset: 0 });
|
|
141
|
+
allSignals.push(...extractMarketSignals(listing, reviews));
|
|
142
|
+
}
|
|
143
|
+
const needs = deriveMarketNeeds(allSignals);
|
|
144
|
+
return {
|
|
145
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
146
|
+
listingsConsidered: listings.length,
|
|
147
|
+
signals: allSignals,
|
|
148
|
+
needs
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export {
|
|
153
|
+
extractMarketSignals,
|
|
154
|
+
deriveMarketNeeds,
|
|
155
|
+
runMarketDiscovery
|
|
156
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// src/marketDiscovery.ts
|
|
2
|
+
var toLower = (v) => String(v ?? "").toLowerCase();
|
|
3
|
+
var clamp01 = (n) => Math.max(0, Math.min(1, n));
|
|
4
|
+
var categorize = (text) => {
|
|
5
|
+
const t = toLower(text);
|
|
6
|
+
const has = (arr) => arr.some((p) => t.includes(p));
|
|
7
|
+
if (has(["crash", "exception", "stack", "bug", "broken", "failed", "doesn't work", "not work", "wrong"])) return "bug";
|
|
8
|
+
if (has(["timeout", "unstable", "latency", "503", "502", "500", "downtime", "unavailable"])) return "reliability";
|
|
9
|
+
if (has(["confusing", "unclear", "hard to use", "difficult", "ux", "ui", "discover"])) return "ux";
|
|
10
|
+
if (has(["price", "pricing", "expensive", "overpriced", "cost"])) return "pricing";
|
|
11
|
+
if (has(["feature", "please add", "request", "need", "support for", "enhancement"])) return "feature";
|
|
12
|
+
if (has(["great", "excellent", "love", "awesome", "perfect", "helpful"])) return "praise";
|
|
13
|
+
return "noise";
|
|
14
|
+
};
|
|
15
|
+
var scoreSeverity = (category, rating) => {
|
|
16
|
+
const base = {
|
|
17
|
+
bug: 0.95,
|
|
18
|
+
reliability: 0.9,
|
|
19
|
+
ux: 0.6,
|
|
20
|
+
pricing: 0.5,
|
|
21
|
+
feature: 0.55,
|
|
22
|
+
praise: 0.15,
|
|
23
|
+
noise: 0.1
|
|
24
|
+
};
|
|
25
|
+
const r = typeof rating === "number" ? rating : void 0;
|
|
26
|
+
const ratingPenalty = r !== void 0 ? clamp01((5 - r) / 5) : 0;
|
|
27
|
+
return clamp01(base[category] * (0.7 + 0.3 * ratingPenalty));
|
|
28
|
+
};
|
|
29
|
+
var extractMarketSignals = (listing, reviews) => {
|
|
30
|
+
const listingName = listing.name;
|
|
31
|
+
const listingId = listing.id;
|
|
32
|
+
return reviews.map((review) => {
|
|
33
|
+
const text = String(review.comment ?? review.text ?? "").trim();
|
|
34
|
+
if (!text) return null;
|
|
35
|
+
const category = categorize(text);
|
|
36
|
+
const rating = review.rating ?? void 0;
|
|
37
|
+
const severity = scoreSeverity(category, typeof rating === "number" ? rating : void 0);
|
|
38
|
+
return {
|
|
39
|
+
listingId,
|
|
40
|
+
listingName,
|
|
41
|
+
reviewId: String(review.id ?? ""),
|
|
42
|
+
createdAt: review.created_at ?? review.createdAt,
|
|
43
|
+
rating: typeof rating === "number" ? rating : void 0,
|
|
44
|
+
text,
|
|
45
|
+
category,
|
|
46
|
+
severity
|
|
47
|
+
};
|
|
48
|
+
}).filter(Boolean);
|
|
49
|
+
};
|
|
50
|
+
var needKeyFromSignal = (s) => {
|
|
51
|
+
return `${s.category}`;
|
|
52
|
+
};
|
|
53
|
+
var deriveMarketNeeds = (signals) => {
|
|
54
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
55
|
+
for (const s of signals) {
|
|
56
|
+
const key = needKeyFromSignal(s);
|
|
57
|
+
const arr = buckets.get(key) ?? [];
|
|
58
|
+
arr.push(s);
|
|
59
|
+
buckets.set(key, arr);
|
|
60
|
+
}
|
|
61
|
+
const needs = [];
|
|
62
|
+
for (const [key, arr] of buckets.entries()) {
|
|
63
|
+
const evidenceCount = arr.length;
|
|
64
|
+
const avgSeverity = arr.reduce((a, b) => a + b.severity, 0) / Math.max(1, arr.length);
|
|
65
|
+
const categories = {};
|
|
66
|
+
for (const s of arr) categories[s.category] = (categories[s.category] ?? 0) + 1;
|
|
67
|
+
const topEvidence = arr.slice().sort((a, b) => b.severity - a.severity).slice(0, 3).map((s) => ({ listingId: s.listingId, reviewId: s.reviewId, text: s.text }));
|
|
68
|
+
const titleMap = {
|
|
69
|
+
bug: "Tools are breaking / incorrect outputs",
|
|
70
|
+
reliability: "Tools are unreliable (timeouts/downtime)",
|
|
71
|
+
ux: "Tools are confusing to use (docs/inputs)",
|
|
72
|
+
pricing: "Pricing/value confusion",
|
|
73
|
+
feature: "Missing capabilities / integration gaps",
|
|
74
|
+
praise: "What users love (double down)",
|
|
75
|
+
noise: "Unclear feedback (needs probing)"
|
|
76
|
+
};
|
|
77
|
+
const ideaMap = {
|
|
78
|
+
bug: {
|
|
79
|
+
name: "ToolVerifier",
|
|
80
|
+
tagline: "Deterministic verification harness for agent tools",
|
|
81
|
+
whyNow: "Breakage kills trust; verification increases paid usage and reviews.",
|
|
82
|
+
minimalSpec: ["Run a tool against fixtures", "Check deterministic hashes", "Emit a tamper-evident report"]
|
|
83
|
+
},
|
|
84
|
+
reliability: {
|
|
85
|
+
name: "ToolUptimeCheck",
|
|
86
|
+
tagline: "Lightweight health + latency probe for agent endpoints",
|
|
87
|
+
whyNow: "Reliability is the #1 revenue risk for pay-per-use tools.",
|
|
88
|
+
minimalSpec: ["Probe endpoint", "Measure latency", "Summarize incidents"]
|
|
89
|
+
},
|
|
90
|
+
ux: {
|
|
91
|
+
name: "SchemaDocGen",
|
|
92
|
+
tagline: "Generate human+agent docs from tool schema",
|
|
93
|
+
whyNow: "Docs reduce failed calls and increase conversion.",
|
|
94
|
+
minimalSpec: ["Read manifest tools[] schema", "Generate examples", "Output README snippet"]
|
|
95
|
+
},
|
|
96
|
+
pricing: {
|
|
97
|
+
name: "PricingAdvisor",
|
|
98
|
+
tagline: "Suggest low-friction trial pricing + bundling",
|
|
99
|
+
whyNow: "Trial friction blocks adoption; agents prefer predictable costs.",
|
|
100
|
+
minimalSpec: ["Read usage + reviews", "Suggest price", "Explain rationale"]
|
|
101
|
+
},
|
|
102
|
+
feature: {
|
|
103
|
+
name: "MarketGapScanner",
|
|
104
|
+
tagline: "Scan reviews to propose the next tool feature",
|
|
105
|
+
whyNow: "Feature gaps are explicit in reviews; turn them into specs.",
|
|
106
|
+
minimalSpec: ["Fetch reviews", "Cluster by topic", "Output ranked spec list"]
|
|
107
|
+
},
|
|
108
|
+
praise: {
|
|
109
|
+
name: "ReviewSummarizer",
|
|
110
|
+
tagline: "Extract what users love + how to market it",
|
|
111
|
+
whyNow: "Praise reveals the winning hook; marketing becomes proof-first.",
|
|
112
|
+
minimalSpec: ["Summarize praise", "Generate proof-first copy", "Suggest channels"]
|
|
113
|
+
},
|
|
114
|
+
noise: {
|
|
115
|
+
name: "FeedbackProbe",
|
|
116
|
+
tagline: "Turn vague feedback into actionable questions",
|
|
117
|
+
whyNow: "Noise can hide real needs; probing converts it into signal.",
|
|
118
|
+
minimalSpec: ["Detect vague review", "Generate clarifying questions", "Propose next step"]
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
needs.push({
|
|
122
|
+
key,
|
|
123
|
+
title: titleMap[key] ?? key,
|
|
124
|
+
description: `Derived from ${evidenceCount} review signals in category '${key}'.`,
|
|
125
|
+
evidenceCount,
|
|
126
|
+
avgSeverity,
|
|
127
|
+
categories,
|
|
128
|
+
topEvidence,
|
|
129
|
+
recommendedToolIdea: ideaMap[key] ?? ideaMap.noise
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return needs.sort((a, b) => b.avgSeverity * b.evidenceCount - a.avgSeverity * a.evidenceCount);
|
|
133
|
+
};
|
|
134
|
+
var discoverMarketNeeds = deriveMarketNeeds;
|
|
135
|
+
var runMarketDiscovery = async (client, options = {}) => {
|
|
136
|
+
const listingsLimit = options.listingsLimit ?? 10;
|
|
137
|
+
const reviewsPerListing = options.reviewsPerListing ?? 20;
|
|
138
|
+
const listings = await client.listAgentListings({ limit: listingsLimit, offset: 0 });
|
|
139
|
+
const allSignals = [];
|
|
140
|
+
for (const listing of listings) {
|
|
141
|
+
const reviews = await client.getListingReviews(listing.id, { limit: reviewsPerListing, offset: 0 });
|
|
142
|
+
allSignals.push(...extractMarketSignals(listing, reviews));
|
|
143
|
+
}
|
|
144
|
+
const needs = deriveMarketNeeds(allSignals);
|
|
145
|
+
return {
|
|
146
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
147
|
+
listingsConsidered: listings.length,
|
|
148
|
+
signals: allSignals,
|
|
149
|
+
needs
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export {
|
|
154
|
+
extractMarketSignals,
|
|
155
|
+
deriveMarketNeeds,
|
|
156
|
+
discoverMarketNeeds,
|
|
157
|
+
runMarketDiscovery
|
|
158
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -4,6 +4,10 @@ import { SelfReliancePolicy } from './selfReliance.js';
|
|
|
4
4
|
export { SelfReliance, createAutoSelfReliance, createSelfRelianceMonitor, createSelfReliancePolicy, createSurvivalMiddleware, withSurvival } from './selfReliance.js';
|
|
5
5
|
import { ReflectionCycleOptions, ReflectionCycleResult } from './reflection.js';
|
|
6
6
|
export { ReflectionActionStatus, ReflectionCandidate, ReflectionCategory, ReflectionCheckpoint, ReflectionClient, ReflectionPlan, ReflectionStore, buildReflectionBacklog, buildReflectionCandidate, bumpSemver, classifyReview, createInMemoryReflectionStore, runReflectionCycle, scoreReviewPriority } from './reflection.js';
|
|
7
|
+
export { SurvivalMode, SurvivalRecommendation, classifySurvivalMode, formatSurvivalRecommendation, getSurvivalRecommendation } from './survivalPlaybook.js';
|
|
8
|
+
export { SurvivalIntegrationDecision, getSurvivalPlaybookDecision, getSurvivalPlaybookDecisionFromSelfReliance } from './survivalIntegration.js';
|
|
9
|
+
export { AgentLoopConfig, AgentLoopContext, AgentLoopHooks, createAgentLoop } from './agentLoop.js';
|
|
10
|
+
export { MarketDiscoveryClient, MarketNeed, MarketSignal, deriveMarketNeeds, discoverMarketNeeds, extractMarketSignals, runMarketDiscovery } from './marketDiscovery.js';
|
|
7
11
|
export { fetchSolBalance, fetchTokenBalance, fetchTokenBalances } from './solana.js';
|
|
8
12
|
import '@coral-xyz/anchor';
|
|
9
13
|
|
|
@@ -681,6 +685,33 @@ declare const VIBEIAO_IDL: {
|
|
|
681
685
|
}];
|
|
682
686
|
};
|
|
683
687
|
|
|
688
|
+
type ContextPackSectionKey = 'objective' | 'mustKnow' | 'risks' | 'decisions' | 'checklist' | 'sources';
|
|
689
|
+
type ContextPackSections = Record<ContextPackSectionKey, string[]>;
|
|
690
|
+
type ContextPackBudget = {
|
|
691
|
+
maxChars: number;
|
|
692
|
+
maxTokens: number;
|
|
693
|
+
usedChars: number;
|
|
694
|
+
usedTokens: number;
|
|
695
|
+
truncated: boolean;
|
|
696
|
+
};
|
|
697
|
+
type ContextPack = {
|
|
698
|
+
schema: 'context-pack/v1';
|
|
699
|
+
createdAt: string;
|
|
700
|
+
budget: ContextPackBudget;
|
|
701
|
+
sections: ContextPackSections;
|
|
702
|
+
};
|
|
703
|
+
type ContextPackInput = Partial<Record<ContextPackSectionKey, string | string[]>>;
|
|
704
|
+
type ContextPackOptions = {
|
|
705
|
+
maxChars?: number;
|
|
706
|
+
maxTokens?: number;
|
|
707
|
+
createdAt?: Date | string;
|
|
708
|
+
maxItemChars?: number;
|
|
709
|
+
};
|
|
710
|
+
declare const createContextPack: (input: ContextPackInput, options?: ContextPackOptions) => ContextPack;
|
|
711
|
+
declare const validateContextPack: (value: unknown) => value is ContextPack;
|
|
712
|
+
declare const CONTEXT_PACK_SECTION_ORDER: ContextPackSectionKey[];
|
|
713
|
+
declare const estimateContextPackTokens: (textOrChars: string | number) => number;
|
|
714
|
+
|
|
684
715
|
interface VibeClientOptions {
|
|
685
716
|
baseUrl?: string;
|
|
686
717
|
fetcher?: typeof fetch;
|
|
@@ -1102,4 +1133,4 @@ declare const getResourceSnapshot: (options: {
|
|
|
1102
1133
|
apiBase?: string;
|
|
1103
1134
|
}) => Promise<ResourceSnapshot>;
|
|
1104
1135
|
|
|
1105
|
-
export { type AgentResourceProvidersManifest, type AnalyticsPoint, type ApiCreditProvider, type ApiCreditProviderFactoryOptions, type ApiCreditProviderPreset, type ApiCreditProviderPresetInput, type ApiResponse, type BuybackEvent, ClaimPurpose, ClaimResponse, LISTING_NAME_MAX_LENGTH, LISTING_NAME_RECOMMENDED_MAX, LISTING_TAGLINE_MAX_LENGTH, LISTING_TAGLINE_RECOMMENDED_MAX, type LeaderboardEntry, type LeaderboardQuery, ListingInput, type ListingNamingValidationOptions, type ListingNamingValidationResult, type ListingQuery, ListingRecord, type ListingReviewCreatePayload, ListingReviewRecord, type ListingReviewResponsePayload, ListingStatus, ListingType, type ListingVersionPayload, type MarketingCampaign, type MarketingLinkOptions, type MemoryPingChallengeResponse, type MemoryPingPayload, type OpenRouterCredits, type ProcurementCandidate, type ProcurementDecision, type ProcurementTaskProfile, type ProcurementWeights, ReflectionCycleOptions, ReflectionCycleResult, type ResourceProviderManifestEntry, type ResourceSnapshot, ReviewGate, type ReviewGateRecord, type ReviewRequiredPayload, type SdkUpdateCheckOptions, type SdkUpdatePolicyCheckOptions, SdkUpdateRequiredError, type SdkUpdateStatus, TicketVerifyResponse, VIBEIAO_IDL, VerifiedClaimResponse, VibeClient, type VibeClientOptions, VibeRegistry, assertSurvivalProvidersConfigured, buildBadgeMarkdown, buildClaimMessage, buildJupiterSwapUrl, buildListingVersionMessage, buildMemoryPingMessage, buildOwnerTransferMessage, buildProcurementPrompt, buildRaydiumSwapUrl, buildReviewPrompt, buildReviewRequired, buildReviewResponseMessage, buildSdkUpdateCommand, buildShareCopy, buildShareLink, buildTradeLinks, checkForSdkUpdate, checkForSdkUpdatePolicy, compareVersions, createApiCreditProvider, createApiCreditProviders, createApiCreditProvidersFromManifest, createCampaign, decideProcurementForTask, getResourceSnapshot, normalizeListingText, rankListingsForTask, sanitizeListingNaming, scoreListingForTask, validateListingNaming };
|
|
1136
|
+
export { type AgentResourceProvidersManifest, type AnalyticsPoint, type ApiCreditProvider, type ApiCreditProviderFactoryOptions, type ApiCreditProviderPreset, type ApiCreditProviderPresetInput, type ApiResponse, type BuybackEvent, CONTEXT_PACK_SECTION_ORDER, ClaimPurpose, ClaimResponse, type ContextPack, type ContextPackBudget, type ContextPackInput, type ContextPackOptions, type ContextPackSectionKey, type ContextPackSections, LISTING_NAME_MAX_LENGTH, LISTING_NAME_RECOMMENDED_MAX, LISTING_TAGLINE_MAX_LENGTH, LISTING_TAGLINE_RECOMMENDED_MAX, type LeaderboardEntry, type LeaderboardQuery, ListingInput, type ListingNamingValidationOptions, type ListingNamingValidationResult, type ListingQuery, ListingRecord, type ListingReviewCreatePayload, ListingReviewRecord, type ListingReviewResponsePayload, ListingStatus, ListingType, type ListingVersionPayload, type MarketingCampaign, type MarketingLinkOptions, type MemoryPingChallengeResponse, type MemoryPingPayload, type OpenRouterCredits, type ProcurementCandidate, type ProcurementDecision, type ProcurementTaskProfile, type ProcurementWeights, ReflectionCycleOptions, ReflectionCycleResult, type ResourceProviderManifestEntry, type ResourceSnapshot, ReviewGate, type ReviewGateRecord, type ReviewRequiredPayload, type SdkUpdateCheckOptions, type SdkUpdatePolicyCheckOptions, SdkUpdateRequiredError, type SdkUpdateStatus, TicketVerifyResponse, VIBEIAO_IDL, VerifiedClaimResponse, VibeClient, type VibeClientOptions, VibeRegistry, assertSurvivalProvidersConfigured, buildBadgeMarkdown, buildClaimMessage, buildJupiterSwapUrl, buildListingVersionMessage, buildMemoryPingMessage, buildOwnerTransferMessage, buildProcurementPrompt, buildRaydiumSwapUrl, buildReviewPrompt, buildReviewRequired, buildReviewResponseMessage, buildSdkUpdateCommand, buildShareCopy, buildShareLink, buildTradeLinks, checkForSdkUpdate, checkForSdkUpdatePolicy, compareVersions, createApiCreditProvider, createApiCreditProviders, createApiCreditProvidersFromManifest, createCampaign, createContextPack, decideProcurementForTask, estimateContextPackTokens, getResourceSnapshot, normalizeListingText, rankListingsForTask, sanitizeListingNaming, scoreListingForTask, validateContextPack, validateListingNaming };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createAgentLoop
|
|
3
|
+
} from "./chunk-7JT4JPEY.js";
|
|
4
|
+
import {
|
|
5
|
+
deriveMarketNeeds,
|
|
6
|
+
discoverMarketNeeds,
|
|
7
|
+
extractMarketSignals,
|
|
8
|
+
runMarketDiscovery
|
|
9
|
+
} from "./chunk-ZMUFCYW6.js";
|
|
1
10
|
import {
|
|
2
11
|
buildReflectionBacklog,
|
|
3
12
|
buildReflectionCandidate,
|
|
@@ -21,6 +30,196 @@ import {
|
|
|
21
30
|
fetchTokenBalance,
|
|
22
31
|
fetchTokenBalances
|
|
23
32
|
} from "./chunk-OUGOOS3F.js";
|
|
33
|
+
import {
|
|
34
|
+
getSurvivalPlaybookDecision,
|
|
35
|
+
getSurvivalPlaybookDecisionFromSelfReliance
|
|
36
|
+
} from "./chunk-A2ORQN53.js";
|
|
37
|
+
import {
|
|
38
|
+
classifySurvivalMode,
|
|
39
|
+
formatSurvivalRecommendation,
|
|
40
|
+
getSurvivalRecommendation
|
|
41
|
+
} from "./chunk-JQE72P4C.js";
|
|
42
|
+
|
|
43
|
+
// src/contextPack.ts
|
|
44
|
+
var SECTION_ORDER = [
|
|
45
|
+
"objective",
|
|
46
|
+
"mustKnow",
|
|
47
|
+
"risks",
|
|
48
|
+
"decisions",
|
|
49
|
+
"checklist",
|
|
50
|
+
"sources"
|
|
51
|
+
];
|
|
52
|
+
var DEFAULT_MAX_CHARS = 2400;
|
|
53
|
+
var DEFAULT_MAX_TOKENS = 700;
|
|
54
|
+
var DEFAULT_MAX_ITEM_CHARS = 320;
|
|
55
|
+
var normalizeItem = (value, maxItemChars) => {
|
|
56
|
+
const compact = value.replace(/\s+/g, " ").trim();
|
|
57
|
+
if (!compact) return "";
|
|
58
|
+
if (compact.length <= maxItemChars) return compact;
|
|
59
|
+
return `${compact.slice(0, Math.max(0, maxItemChars - 1)).trimEnd()}\u2026`;
|
|
60
|
+
};
|
|
61
|
+
var normalizeSectionInput = (value, maxItemChars) => {
|
|
62
|
+
if (!value) return [];
|
|
63
|
+
const list = Array.isArray(value) ? value : [value];
|
|
64
|
+
const seen = /* @__PURE__ */ new Set();
|
|
65
|
+
const output = [];
|
|
66
|
+
for (const item of list) {
|
|
67
|
+
const normalized = normalizeItem(String(item ?? ""), maxItemChars);
|
|
68
|
+
if (!normalized || seen.has(normalized)) continue;
|
|
69
|
+
seen.add(normalized);
|
|
70
|
+
output.push(normalized);
|
|
71
|
+
}
|
|
72
|
+
return output;
|
|
73
|
+
};
|
|
74
|
+
var estimateTokensFromChars = (chars) => Math.ceil(chars / 4);
|
|
75
|
+
var buildSections = (input, maxItemChars) => ({
|
|
76
|
+
objective: normalizeSectionInput(input.objective, maxItemChars),
|
|
77
|
+
mustKnow: normalizeSectionInput(input.mustKnow, maxItemChars),
|
|
78
|
+
risks: normalizeSectionInput(input.risks, maxItemChars),
|
|
79
|
+
decisions: normalizeSectionInput(input.decisions, maxItemChars),
|
|
80
|
+
checklist: normalizeSectionInput(input.checklist, maxItemChars),
|
|
81
|
+
sources: normalizeSectionInput(input.sources, maxItemChars)
|
|
82
|
+
});
|
|
83
|
+
var copySections = (sections) => ({
|
|
84
|
+
objective: [...sections.objective],
|
|
85
|
+
mustKnow: [...sections.mustKnow],
|
|
86
|
+
risks: [...sections.risks],
|
|
87
|
+
decisions: [...sections.decisions],
|
|
88
|
+
checklist: [...sections.checklist],
|
|
89
|
+
sources: [...sections.sources]
|
|
90
|
+
});
|
|
91
|
+
var measuredJson = (sections) => {
|
|
92
|
+
const json = JSON.stringify(
|
|
93
|
+
{
|
|
94
|
+
schema: "context-pack/v1",
|
|
95
|
+
sections: {
|
|
96
|
+
objective: sections.objective,
|
|
97
|
+
mustKnow: sections.mustKnow,
|
|
98
|
+
risks: sections.risks,
|
|
99
|
+
decisions: sections.decisions,
|
|
100
|
+
checklist: sections.checklist,
|
|
101
|
+
sources: sections.sources
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
null,
|
|
105
|
+
2
|
|
106
|
+
);
|
|
107
|
+
const chars = json.length;
|
|
108
|
+
const tokens = estimateTokensFromChars(chars);
|
|
109
|
+
return { chars, tokens };
|
|
110
|
+
};
|
|
111
|
+
var fitsBudget = (sections, maxChars, maxTokens) => {
|
|
112
|
+
const measured = measuredJson(sections);
|
|
113
|
+
return measured.chars <= maxChars && measured.tokens <= maxTokens;
|
|
114
|
+
};
|
|
115
|
+
var truncateToBudget = (sections, maxChars, maxTokens) => {
|
|
116
|
+
const out = {
|
|
117
|
+
objective: [],
|
|
118
|
+
mustKnow: [],
|
|
119
|
+
risks: [],
|
|
120
|
+
decisions: [],
|
|
121
|
+
checklist: [],
|
|
122
|
+
sources: []
|
|
123
|
+
};
|
|
124
|
+
for (const key of SECTION_ORDER) {
|
|
125
|
+
for (const item of sections[key]) {
|
|
126
|
+
out[key].push(item);
|
|
127
|
+
if (fitsBudget(out, maxChars, maxTokens)) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
out[key].pop();
|
|
131
|
+
const probe = `${item.slice(0, Math.max(0, item.length - 1)).trimEnd()}\u2026`;
|
|
132
|
+
if (probe.length >= 16) {
|
|
133
|
+
let lo = 16;
|
|
134
|
+
let hi = probe.length;
|
|
135
|
+
let best = "";
|
|
136
|
+
while (lo <= hi) {
|
|
137
|
+
const mid = Math.floor((lo + hi) / 2);
|
|
138
|
+
const candidate = `${probe.slice(0, Math.max(0, mid - 1)).trimEnd()}\u2026`;
|
|
139
|
+
out[key].push(candidate);
|
|
140
|
+
const ok = fitsBudget(out, maxChars, maxTokens);
|
|
141
|
+
out[key].pop();
|
|
142
|
+
if (ok) {
|
|
143
|
+
best = candidate;
|
|
144
|
+
lo = mid + 1;
|
|
145
|
+
} else {
|
|
146
|
+
hi = mid - 1;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (best) {
|
|
150
|
+
out[key].push(best);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return out;
|
|
157
|
+
};
|
|
158
|
+
var normalizeCreatedAt = (value) => {
|
|
159
|
+
if (!value) return (/* @__PURE__ */ new Date()).toISOString();
|
|
160
|
+
if (value instanceof Date) return value.toISOString();
|
|
161
|
+
const parsed = new Date(value);
|
|
162
|
+
if (Number.isFinite(parsed.getTime())) return parsed.toISOString();
|
|
163
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
164
|
+
};
|
|
165
|
+
var createContextPack = (input, options = {}) => {
|
|
166
|
+
const maxChars = Math.max(240, Number(options.maxChars ?? DEFAULT_MAX_CHARS));
|
|
167
|
+
const maxTokens = Math.max(80, Number(options.maxTokens ?? DEFAULT_MAX_TOKENS));
|
|
168
|
+
const maxItemChars = Math.max(16, Number(options.maxItemChars ?? DEFAULT_MAX_ITEM_CHARS));
|
|
169
|
+
const normalized = buildSections(input, maxItemChars);
|
|
170
|
+
const withinBudget = fitsBudget(normalized, maxChars, maxTokens);
|
|
171
|
+
const sections = withinBudget ? copySections(normalized) : truncateToBudget(normalized, maxChars, maxTokens);
|
|
172
|
+
const usage = measuredJson(sections);
|
|
173
|
+
return {
|
|
174
|
+
schema: "context-pack/v1",
|
|
175
|
+
createdAt: normalizeCreatedAt(options.createdAt),
|
|
176
|
+
budget: {
|
|
177
|
+
maxChars,
|
|
178
|
+
maxTokens,
|
|
179
|
+
usedChars: usage.chars,
|
|
180
|
+
usedTokens: usage.tokens,
|
|
181
|
+
truncated: !withinBudget
|
|
182
|
+
},
|
|
183
|
+
sections: {
|
|
184
|
+
objective: sections.objective,
|
|
185
|
+
mustKnow: sections.mustKnow,
|
|
186
|
+
risks: sections.risks,
|
|
187
|
+
decisions: sections.decisions,
|
|
188
|
+
checklist: sections.checklist,
|
|
189
|
+
sources: sections.sources
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
var validateContextPack = (value) => {
|
|
194
|
+
if (!value || typeof value !== "object") return false;
|
|
195
|
+
const pack = value;
|
|
196
|
+
if (pack.schema !== "context-pack/v1") return false;
|
|
197
|
+
if (!pack.budget || typeof pack.budget !== "object") return false;
|
|
198
|
+
const budget = pack.budget;
|
|
199
|
+
const budgetFields = [
|
|
200
|
+
"maxChars",
|
|
201
|
+
"maxTokens",
|
|
202
|
+
"usedChars",
|
|
203
|
+
"usedTokens",
|
|
204
|
+
"truncated"
|
|
205
|
+
];
|
|
206
|
+
for (const field of budgetFields) {
|
|
207
|
+
if (!(field in budget)) return false;
|
|
208
|
+
}
|
|
209
|
+
if (typeof budget.truncated !== "boolean") return false;
|
|
210
|
+
for (const field of ["maxChars", "maxTokens", "usedChars", "usedTokens"]) {
|
|
211
|
+
if (!Number.isFinite(Number(budget[field]))) return false;
|
|
212
|
+
}
|
|
213
|
+
if (!pack.sections || typeof pack.sections !== "object") return false;
|
|
214
|
+
const sections = pack.sections;
|
|
215
|
+
for (const key of SECTION_ORDER) {
|
|
216
|
+
if (!Array.isArray(sections[key])) return false;
|
|
217
|
+
if (sections[key].some((item) => typeof item !== "string")) return false;
|
|
218
|
+
}
|
|
219
|
+
return true;
|
|
220
|
+
};
|
|
221
|
+
var CONTEXT_PACK_SECTION_ORDER = [...SECTION_ORDER];
|
|
222
|
+
var estimateContextPackTokens = (textOrChars) => estimateTokensFromChars(typeof textOrChars === "number" ? textOrChars : textOrChars.length);
|
|
24
223
|
|
|
25
224
|
// src/index.ts
|
|
26
225
|
var SdkUpdateRequiredError = class extends Error {
|
|
@@ -123,7 +322,7 @@ var ReviewGate = class {
|
|
|
123
322
|
var DEFAULT_API_BASE = "https://api.vibeiao.com";
|
|
124
323
|
var DEFAULT_WEB_BASE = "https://vibeiao.com";
|
|
125
324
|
var DEFAULT_SDK_PACKAGE = "@vibeiao/sdk";
|
|
126
|
-
var DEFAULT_SDK_VERSION = "0.1.
|
|
325
|
+
var DEFAULT_SDK_VERSION = "0.1.25" ? "0.1.25" : "0.1.4";
|
|
127
326
|
var DEFAULT_SDK_REGISTRY = "https://registry.npmjs.org";
|
|
128
327
|
var DEFAULT_SDK_POLICY_PATH = "/v1/sdk/policy";
|
|
129
328
|
var DEFAULT_SDK_CHECK_INTERVAL_MS = 1e3 * 60 * 30;
|
|
@@ -1100,6 +1299,7 @@ var getResourceSnapshot = async (options) => {
|
|
|
1100
1299
|
return snapshot;
|
|
1101
1300
|
};
|
|
1102
1301
|
export {
|
|
1302
|
+
CONTEXT_PACK_SECTION_ORDER,
|
|
1103
1303
|
LISTING_NAME_MAX_LENGTH,
|
|
1104
1304
|
LISTING_NAME_RECOMMENDED_MAX,
|
|
1105
1305
|
LISTING_TAGLINE_MAX_LENGTH,
|
|
@@ -1132,27 +1332,40 @@ export {
|
|
|
1132
1332
|
checkForSdkUpdate,
|
|
1133
1333
|
checkForSdkUpdatePolicy,
|
|
1134
1334
|
classifyReview,
|
|
1335
|
+
classifySurvivalMode,
|
|
1135
1336
|
compareVersions,
|
|
1337
|
+
createAgentLoop,
|
|
1136
1338
|
createApiCreditProvider,
|
|
1137
1339
|
createApiCreditProviders,
|
|
1138
1340
|
createApiCreditProvidersFromManifest,
|
|
1139
1341
|
createAutoSelfReliance,
|
|
1140
1342
|
createCampaign,
|
|
1343
|
+
createContextPack,
|
|
1141
1344
|
createInMemoryReflectionStore,
|
|
1142
1345
|
createSelfRelianceMonitor,
|
|
1143
1346
|
createSelfReliancePolicy,
|
|
1144
1347
|
createSurvivalMiddleware,
|
|
1145
1348
|
decideProcurementForTask,
|
|
1349
|
+
deriveMarketNeeds,
|
|
1350
|
+
discoverMarketNeeds,
|
|
1351
|
+
estimateContextPackTokens,
|
|
1352
|
+
extractMarketSignals,
|
|
1146
1353
|
fetchSolBalance,
|
|
1147
1354
|
fetchTokenBalance,
|
|
1148
1355
|
fetchTokenBalances,
|
|
1356
|
+
formatSurvivalRecommendation,
|
|
1149
1357
|
getResourceSnapshot,
|
|
1358
|
+
getSurvivalPlaybookDecision,
|
|
1359
|
+
getSurvivalPlaybookDecisionFromSelfReliance,
|
|
1360
|
+
getSurvivalRecommendation,
|
|
1150
1361
|
normalizeListingText,
|
|
1151
1362
|
rankListingsForTask,
|
|
1363
|
+
runMarketDiscovery,
|
|
1152
1364
|
runReflectionCycle,
|
|
1153
1365
|
sanitizeListingNaming,
|
|
1154
1366
|
scoreListingForTask,
|
|
1155
1367
|
scoreReviewPriority,
|
|
1368
|
+
validateContextPack,
|
|
1156
1369
|
validateListingNaming,
|
|
1157
1370
|
withSurvival
|
|
1158
1371
|
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { L as ListingRecord, e as ListingReviewRecord } from './shared-By5mFIMw.js';
|
|
2
|
+
|
|
3
|
+
type MarketSignal = {
|
|
4
|
+
listingId: string;
|
|
5
|
+
listingName: string;
|
|
6
|
+
reviewId: string;
|
|
7
|
+
createdAt?: string;
|
|
8
|
+
rating?: number;
|
|
9
|
+
text: string;
|
|
10
|
+
category: 'bug' | 'reliability' | 'ux' | 'pricing' | 'feature' | 'praise' | 'noise';
|
|
11
|
+
severity: number;
|
|
12
|
+
};
|
|
13
|
+
type MarketNeed = {
|
|
14
|
+
key: string;
|
|
15
|
+
title: string;
|
|
16
|
+
description: string;
|
|
17
|
+
evidenceCount: number;
|
|
18
|
+
avgSeverity: number;
|
|
19
|
+
categories: Record<string, number>;
|
|
20
|
+
topEvidence: Array<{
|
|
21
|
+
listingId: string;
|
|
22
|
+
reviewId: string;
|
|
23
|
+
text: string;
|
|
24
|
+
}>;
|
|
25
|
+
recommendedToolIdea: {
|
|
26
|
+
name: string;
|
|
27
|
+
tagline: string;
|
|
28
|
+
whyNow: string;
|
|
29
|
+
minimalSpec: string[];
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
type MarketDiscoveryClient = {
|
|
33
|
+
listAgentListings: (options?: {
|
|
34
|
+
limit?: number;
|
|
35
|
+
offset?: number;
|
|
36
|
+
sort?: string;
|
|
37
|
+
}) => Promise<ListingRecord[]>;
|
|
38
|
+
getListingReviews: (listingId: string, options?: {
|
|
39
|
+
limit?: number;
|
|
40
|
+
offset?: number;
|
|
41
|
+
}) => Promise<ListingReviewRecord[]>;
|
|
42
|
+
};
|
|
43
|
+
declare const extractMarketSignals: (listing: ListingRecord, reviews: ListingReviewRecord[]) => MarketSignal[];
|
|
44
|
+
declare const deriveMarketNeeds: (signals: MarketSignal[]) => MarketNeed[];
|
|
45
|
+
declare const discoverMarketNeeds: (signals: MarketSignal[]) => MarketNeed[];
|
|
46
|
+
declare const runMarketDiscovery: (client: MarketDiscoveryClient, options?: {
|
|
47
|
+
listingsLimit?: number;
|
|
48
|
+
reviewsPerListing?: number;
|
|
49
|
+
}) => Promise<{
|
|
50
|
+
generatedAt: string;
|
|
51
|
+
listingsConsidered: number;
|
|
52
|
+
signals: MarketSignal[];
|
|
53
|
+
needs: MarketNeed[];
|
|
54
|
+
}>;
|
|
55
|
+
|
|
56
|
+
export { type MarketDiscoveryClient, type MarketNeed, type MarketSignal, deriveMarketNeeds, discoverMarketNeeds, extractMarketSignals, runMarketDiscovery };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { SelfRelianceState, SelfReliancePolicy, SelfReliance } from './selfReliance.js';
|
|
2
|
+
import { SurvivalMode, SurvivalRecommendation } from './survivalPlaybook.js';
|
|
3
|
+
|
|
4
|
+
type SurvivalIntegrationDecision = {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
mode: SurvivalMode;
|
|
7
|
+
recommendation: SurvivalRecommendation;
|
|
8
|
+
formatted: string;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Safe rollout helper.
|
|
12
|
+
* - If SURVIVAL_PLAYBOOK_ENABLED is not set truthy, returns enabled=false and does not attempt to influence behavior.
|
|
13
|
+
* - If enabled, returns the mode + structured recommendation suitable for injecting into an agent planner.
|
|
14
|
+
*/
|
|
15
|
+
declare const getSurvivalPlaybookDecision: (options: {
|
|
16
|
+
state: SelfRelianceState;
|
|
17
|
+
policy: SelfReliancePolicy;
|
|
18
|
+
enabledEnv?: string;
|
|
19
|
+
}) => SurvivalIntegrationDecision;
|
|
20
|
+
/**
|
|
21
|
+
* Convenience wrapper for agents already using SelfReliance.
|
|
22
|
+
*/
|
|
23
|
+
declare const getSurvivalPlaybookDecisionFromSelfReliance: (survival: SelfReliance) => SurvivalIntegrationDecision;
|
|
24
|
+
|
|
25
|
+
export { type SurvivalIntegrationDecision, getSurvivalPlaybookDecision, getSurvivalPlaybookDecisionFromSelfReliance };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SelfRelianceState, SelfReliancePolicy } from './selfReliance.js';
|
|
2
|
+
|
|
3
|
+
type SurvivalMode = 'EXPAND' | 'FOCUS' | 'SURVIVE' | 'BLINK';
|
|
4
|
+
type SurvivalRecommendation = {
|
|
5
|
+
mode: SurvivalMode;
|
|
6
|
+
summary: string;
|
|
7
|
+
objective: string;
|
|
8
|
+
/** Current spending rule of thumb for this mode (budget gate). */
|
|
9
|
+
spendingPolicy: {
|
|
10
|
+
posture: 'invest' | 'conserve' | 'freeze';
|
|
11
|
+
rule: string;
|
|
12
|
+
};
|
|
13
|
+
/** Aspirational purchases/goals the agent can work toward (non-binding). */
|
|
14
|
+
aspirationalUpgrades: Array<{
|
|
15
|
+
when: string;
|
|
16
|
+
buy: string;
|
|
17
|
+
why: string;
|
|
18
|
+
}>;
|
|
19
|
+
constraints: string[];
|
|
20
|
+
nextActions: Array<{
|
|
21
|
+
label: string;
|
|
22
|
+
rationale: string;
|
|
23
|
+
priority: 'P0' | 'P1' | 'P2';
|
|
24
|
+
}>;
|
|
25
|
+
marketing: {
|
|
26
|
+
principle: string;
|
|
27
|
+
rules: string[];
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
declare const classifySurvivalMode: (state: SelfRelianceState, policy: SelfReliancePolicy) => SurvivalMode;
|
|
31
|
+
declare const getSurvivalRecommendation: (mode: SurvivalMode) => SurvivalRecommendation;
|
|
32
|
+
declare const formatSurvivalRecommendation: (reco: SurvivalRecommendation) => string;
|
|
33
|
+
|
|
34
|
+
export { type SurvivalMode, type SurvivalRecommendation, classifySurvivalMode, formatSurvivalRecommendation, getSurvivalRecommendation };
|