@chrryai/waffles 2.4.41 → 2.4.43
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/index.d.mts +411 -1
- package/dist/index.d.ts +411 -1
- package/dist/index.js +735 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +707 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
var dotenv = require('dotenv');
|
|
4
4
|
var test = require('@playwright/test');
|
|
5
5
|
var faker = require('@faker-js/faker');
|
|
6
|
+
var child_process = require('child_process');
|
|
7
|
+
var crypto = require('crypto');
|
|
8
|
+
var effect = require('effect');
|
|
6
9
|
|
|
7
10
|
function _interopNamespace(e) {
|
|
8
11
|
if (e && e.__esModule) return e;
|
|
@@ -24,7 +27,12 @@ function _interopNamespace(e) {
|
|
|
24
27
|
|
|
25
28
|
var dotenv__namespace = /*#__PURE__*/_interopNamespace(dotenv);
|
|
26
29
|
|
|
27
|
-
|
|
30
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
31
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
32
|
+
}) : x)(function(x) {
|
|
33
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
34
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
35
|
+
});
|
|
28
36
|
var APIClient = class {
|
|
29
37
|
context = null;
|
|
30
38
|
baseURL;
|
|
@@ -140,6 +148,703 @@ var scheduledJobFactory = {
|
|
|
140
148
|
return Array.from({ length: count }, () => this.build(overrides));
|
|
141
149
|
}
|
|
142
150
|
};
|
|
151
|
+
var BRANCH_STORAGE_KEY = "chrry-branch-agents";
|
|
152
|
+
function getStorage() {
|
|
153
|
+
if (typeof globalThis === "undefined") return {};
|
|
154
|
+
try {
|
|
155
|
+
const raw = globalThis[BRANCH_STORAGE_KEY];
|
|
156
|
+
if (raw) return JSON.parse(raw);
|
|
157
|
+
} catch {
|
|
158
|
+
}
|
|
159
|
+
return {};
|
|
160
|
+
}
|
|
161
|
+
function setStorage(data) {
|
|
162
|
+
if (typeof globalThis !== "undefined") {
|
|
163
|
+
globalThis[BRANCH_STORAGE_KEY] = JSON.stringify(data);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function fileStoragePath() {
|
|
167
|
+
try {
|
|
168
|
+
const cwd = process.cwd();
|
|
169
|
+
return `${cwd}/.chrry/branch-agents.json`;
|
|
170
|
+
} catch {
|
|
171
|
+
return void 0;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
function loadFileStorage() {
|
|
175
|
+
const path = fileStoragePath();
|
|
176
|
+
if (!path) return {};
|
|
177
|
+
try {
|
|
178
|
+
const fs = __require("fs");
|
|
179
|
+
if (fs.existsSync(path)) {
|
|
180
|
+
return JSON.parse(fs.readFileSync(path, "utf-8"));
|
|
181
|
+
}
|
|
182
|
+
} catch {
|
|
183
|
+
}
|
|
184
|
+
return {};
|
|
185
|
+
}
|
|
186
|
+
function saveFileStorage(data) {
|
|
187
|
+
const path = fileStoragePath();
|
|
188
|
+
if (!path) return;
|
|
189
|
+
try {
|
|
190
|
+
const fs = __require("fs");
|
|
191
|
+
const dir = path.replace("/branch-agents.json", "");
|
|
192
|
+
if (!fs.existsSync(dir)) {
|
|
193
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
194
|
+
}
|
|
195
|
+
fs.writeFileSync(path, JSON.stringify(data, null, 2));
|
|
196
|
+
} catch {
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function getAllWorkspaces() {
|
|
200
|
+
const mem = getStorage();
|
|
201
|
+
const file = loadFileStorage();
|
|
202
|
+
return { ...file, ...mem };
|
|
203
|
+
}
|
|
204
|
+
function setAllWorkspaces(data) {
|
|
205
|
+
setStorage(data);
|
|
206
|
+
saveFileStorage(data);
|
|
207
|
+
}
|
|
208
|
+
function getCurrentBranch() {
|
|
209
|
+
const envBranch = process.env.CHRRY_BRANCH || process.env.GIT_BRANCH || process.env.GITHUB_HEAD_REF || process.env.CF_PAGES_BRANCH;
|
|
210
|
+
if (envBranch) return envBranch;
|
|
211
|
+
try {
|
|
212
|
+
const branch = child_process.execSync("git branch --show-current", {
|
|
213
|
+
encoding: "utf-8",
|
|
214
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
215
|
+
}).trim();
|
|
216
|
+
if (branch) return branch;
|
|
217
|
+
} catch {
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const desc = child_process.execSync("git describe --all --contains HEAD", {
|
|
221
|
+
encoding: "utf-8",
|
|
222
|
+
stdio: ["pipe", "pipe", "ignore"]
|
|
223
|
+
}).trim();
|
|
224
|
+
if (desc) return desc.replace(/^heads\//, "");
|
|
225
|
+
} catch {
|
|
226
|
+
}
|
|
227
|
+
return void 0;
|
|
228
|
+
}
|
|
229
|
+
function parseBranchName(fullBranch) {
|
|
230
|
+
const parts = fullBranch.split("/");
|
|
231
|
+
if (parts.length >= 2) {
|
|
232
|
+
return {
|
|
233
|
+
namespace: parts.slice(0, -1).join("/"),
|
|
234
|
+
branchName: parts[parts.length - 1]
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
namespace: "default",
|
|
239
|
+
branchName: fullBranch
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function generateAgentId(namespace, branchName) {
|
|
243
|
+
return `agent-${namespace}-${branchName}-${crypto.randomUUID().slice(0, 8)}`;
|
|
244
|
+
}
|
|
245
|
+
function createBranchWorkspace(fullBranchName, overrides) {
|
|
246
|
+
const { namespace, branchName } = parseBranchName(fullBranchName);
|
|
247
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
248
|
+
return {
|
|
249
|
+
id: crypto.randomUUID(),
|
|
250
|
+
namespace,
|
|
251
|
+
branchName,
|
|
252
|
+
fullBranchName,
|
|
253
|
+
agentId: overrides?.agentId || generateAgentId(namespace, branchName),
|
|
254
|
+
systemPrompt: overrides?.systemPrompt || defaultSystemPrompt(namespace, branchName),
|
|
255
|
+
instructions: overrides?.instructions || [],
|
|
256
|
+
memories: overrides?.memories || [],
|
|
257
|
+
characterProfile: overrides?.characterProfile,
|
|
258
|
+
evolutionScore: overrides?.evolutionScore ?? 0,
|
|
259
|
+
lastCommitSha: overrides?.lastCommitSha,
|
|
260
|
+
metadata: overrides?.metadata || {
|
|
261
|
+
createdBy: "branch-agent-system",
|
|
262
|
+
version: "1.0"
|
|
263
|
+
},
|
|
264
|
+
createdOn: overrides?.createdOn || now,
|
|
265
|
+
updatedOn: now
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
function defaultSystemPrompt(namespace, branchName) {
|
|
269
|
+
return `You are the AI agent for the branch "${namespace}/${branchName}".
|
|
270
|
+
Your knowledge, memories, and behavior are isolated to this branch.
|
|
271
|
+
When switching branches, save your current context and load the new one.
|
|
272
|
+
Collaborate with other branch agents via @namespace/branch mentions.`;
|
|
273
|
+
}
|
|
274
|
+
function loadBranchWorkspace(fullBranchName) {
|
|
275
|
+
const workspaces = getAllWorkspaces();
|
|
276
|
+
return workspaces[fullBranchName];
|
|
277
|
+
}
|
|
278
|
+
function saveBranchWorkspace(workspace) {
|
|
279
|
+
const workspaces = getAllWorkspaces();
|
|
280
|
+
workspace.updatedOn = (/* @__PURE__ */ new Date()).toISOString();
|
|
281
|
+
workspaces[workspace.fullBranchName] = workspace;
|
|
282
|
+
setAllWorkspaces(workspaces);
|
|
283
|
+
return workspace;
|
|
284
|
+
}
|
|
285
|
+
function getOrCreateBranchWorkspace(fullBranchName) {
|
|
286
|
+
const existing = loadBranchWorkspace(fullBranchName);
|
|
287
|
+
if (existing) return existing;
|
|
288
|
+
const created = createBranchWorkspace(fullBranchName);
|
|
289
|
+
return saveBranchWorkspace(created);
|
|
290
|
+
}
|
|
291
|
+
function switchBranchContext(newBranch, previousBranch) {
|
|
292
|
+
const { namespace, branchName } = parseBranchName(newBranch);
|
|
293
|
+
if (previousBranch) {
|
|
294
|
+
const prevWorkspace = loadBranchWorkspace(previousBranch);
|
|
295
|
+
if (prevWorkspace) {
|
|
296
|
+
saveBranchWorkspace(prevWorkspace);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const workspace = getOrCreateBranchWorkspace(newBranch);
|
|
300
|
+
return {
|
|
301
|
+
currentBranch: newBranch,
|
|
302
|
+
namespace,
|
|
303
|
+
branchName,
|
|
304
|
+
workspace,
|
|
305
|
+
previousBranch
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function autoDetectAndSwitch(previousBranch) {
|
|
309
|
+
const current = getCurrentBranch();
|
|
310
|
+
if (!current) return void 0;
|
|
311
|
+
if (current === previousBranch) {
|
|
312
|
+
return {
|
|
313
|
+
currentBranch: current,
|
|
314
|
+
...parseBranchName(current),
|
|
315
|
+
workspace: loadBranchWorkspace(current),
|
|
316
|
+
previousBranch
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
return switchBranchContext(current, previousBranch);
|
|
320
|
+
}
|
|
321
|
+
function deleteBranchWorkspace(fullBranchName) {
|
|
322
|
+
const workspaces = getAllWorkspaces();
|
|
323
|
+
if (!workspaces[fullBranchName]) return false;
|
|
324
|
+
delete workspaces[fullBranchName];
|
|
325
|
+
setAllWorkspaces(workspaces);
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
function recordMutation(fullBranchName, mutation) {
|
|
329
|
+
const workspace = loadBranchWorkspace(fullBranchName);
|
|
330
|
+
if (!workspace) return void 0;
|
|
331
|
+
const mutations = workspace.metadata.mutations || [];
|
|
332
|
+
mutations.push({
|
|
333
|
+
...mutation,
|
|
334
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
335
|
+
});
|
|
336
|
+
const successCount = mutations.filter((m) => m.success).length;
|
|
337
|
+
workspace.evolutionScore = mutations.length > 0 ? successCount / mutations.length : 0;
|
|
338
|
+
workspace.metadata.mutations = mutations.slice(-100);
|
|
339
|
+
return saveBranchWorkspace(workspace);
|
|
340
|
+
}
|
|
341
|
+
function getCurrentBranchSafe() {
|
|
342
|
+
return effect.Effect.sync(() => getCurrentBranch()).pipe(
|
|
343
|
+
effect.Effect.catchAll((e) => effect.Effect.succeed(void 0))
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
function switchBranchContextSafe(newBranch, previousBranch) {
|
|
347
|
+
return effect.Effect.sync(() => switchBranchContext(newBranch, previousBranch)).pipe(
|
|
348
|
+
effect.Effect.catchAll((e) => effect.Effect.fail(String(e)))
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
function autoDetectAndSwitchSafe(previousBranch) {
|
|
352
|
+
return effect.Effect.sync(() => autoDetectAndSwitch(previousBranch)).pipe(
|
|
353
|
+
effect.Effect.catchAll((e) => effect.Effect.fail(String(e)))
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/agent/chopstickExpert.ts
|
|
358
|
+
var modelPricing = {
|
|
359
|
+
"deepseek/deepseek-v3.2": {
|
|
360
|
+
input: 0.28,
|
|
361
|
+
output: 0.4,
|
|
362
|
+
tools: true,
|
|
363
|
+
analyze: false
|
|
364
|
+
},
|
|
365
|
+
"deepseek/deepseek-chat": {
|
|
366
|
+
input: 0.15,
|
|
367
|
+
output: 0.45,
|
|
368
|
+
tools: true,
|
|
369
|
+
analyze: false
|
|
370
|
+
},
|
|
371
|
+
"anthropic/claude-sonnet-4-6": {
|
|
372
|
+
input: 3,
|
|
373
|
+
output: 15,
|
|
374
|
+
tools: true,
|
|
375
|
+
analyze: true
|
|
376
|
+
},
|
|
377
|
+
"google/gemini-3.1-pro-preview": {
|
|
378
|
+
input: 0.35,
|
|
379
|
+
output: 1.05,
|
|
380
|
+
tools: true,
|
|
381
|
+
analyze: true
|
|
382
|
+
},
|
|
383
|
+
"deepseek/deepseek-v3.2-thinking": {
|
|
384
|
+
input: 0.28,
|
|
385
|
+
output: 0.4,
|
|
386
|
+
tools: true,
|
|
387
|
+
analyze: false
|
|
388
|
+
},
|
|
389
|
+
"qwen/qwen3.6-plus": { input: 0.3, output: 0.8, tools: true, analyze: true },
|
|
390
|
+
"minimax/minimax-m2.5": {
|
|
391
|
+
input: 0.3,
|
|
392
|
+
output: 1.1,
|
|
393
|
+
tools: true,
|
|
394
|
+
analyze: false
|
|
395
|
+
},
|
|
396
|
+
"minimax/minimax-m2.7": {
|
|
397
|
+
input: 0.3,
|
|
398
|
+
output: 1.2,
|
|
399
|
+
tools: true,
|
|
400
|
+
analyze: false
|
|
401
|
+
},
|
|
402
|
+
"x-ai/grok-4.1-fast": { input: 0.5, output: 2, tools: true, analyze: true },
|
|
403
|
+
"perplexity/sonar-pro": {
|
|
404
|
+
input: 2,
|
|
405
|
+
output: 8,
|
|
406
|
+
tools: false,
|
|
407
|
+
analyze: false
|
|
408
|
+
},
|
|
409
|
+
"openrouter/free": { input: 0, output: 0, tools: false, analyze: false },
|
|
410
|
+
"openai/gpt-oss-120b:free": {
|
|
411
|
+
input: 0,
|
|
412
|
+
output: 0.073,
|
|
413
|
+
tools: false,
|
|
414
|
+
analyze: true
|
|
415
|
+
},
|
|
416
|
+
"nvidia/nemotron-3-super-120b-a12b:free": {
|
|
417
|
+
input: 0,
|
|
418
|
+
output: 0,
|
|
419
|
+
tools: true,
|
|
420
|
+
analyze: false
|
|
421
|
+
},
|
|
422
|
+
"gpt-4o": { input: 2.5, output: 10, tools: true, analyze: true },
|
|
423
|
+
"gpt-4o-mini": { input: 0.15, output: 0.6, tools: true, analyze: true },
|
|
424
|
+
"openai/gpt-5.4": { input: 2.5, output: 15, tools: true, analyze: true }
|
|
425
|
+
};
|
|
426
|
+
var presets = {
|
|
427
|
+
minimal: {
|
|
428
|
+
join: {
|
|
429
|
+
memories: { user: 1, app: 1, dna: 0, thread: 1 },
|
|
430
|
+
instructions: { user: 1, app: 1, dna: 0, thread: 1 },
|
|
431
|
+
characterProfile: { user: 0, app: 0, dna: 0, thread: 0 },
|
|
432
|
+
placeholders: { user: 1, app: 1, dna: 0, thread: 1 }
|
|
433
|
+
},
|
|
434
|
+
depth: 0,
|
|
435
|
+
model: {
|
|
436
|
+
modelId: "nvidia/nemotron-3-super-120b-a12b:free",
|
|
437
|
+
inputPrice: 0,
|
|
438
|
+
outputPrice: 0,
|
|
439
|
+
hasTools: true,
|
|
440
|
+
canAnalyze: false,
|
|
441
|
+
reason: "Free model, minimal context"
|
|
442
|
+
},
|
|
443
|
+
reasoning: ["Minimal preset"]
|
|
444
|
+
},
|
|
445
|
+
balanced: {
|
|
446
|
+
join: {
|
|
447
|
+
memories: { user: 3, app: 2, dna: 1, thread: 3 },
|
|
448
|
+
instructions: { user: 2, app: 2, dna: 1, thread: 2 },
|
|
449
|
+
characterProfile: { user: 1, app: 1, dna: 0, thread: 1 },
|
|
450
|
+
placeholders: { user: 2, app: 2, dna: 1, thread: 2 }
|
|
451
|
+
},
|
|
452
|
+
depth: 1,
|
|
453
|
+
model: {
|
|
454
|
+
modelId: "deepseek/deepseek-chat",
|
|
455
|
+
inputPrice: 0.15,
|
|
456
|
+
outputPrice: 0.45,
|
|
457
|
+
hasTools: true,
|
|
458
|
+
canAnalyze: false,
|
|
459
|
+
reason: "Balanced cost/performance"
|
|
460
|
+
},
|
|
461
|
+
reasoning: ["Balanced preset"]
|
|
462
|
+
},
|
|
463
|
+
rich: {
|
|
464
|
+
join: {
|
|
465
|
+
memories: { user: 8, app: 5, dna: 3, thread: 6 },
|
|
466
|
+
instructions: { user: 5, app: 4, dna: 2, thread: 4 },
|
|
467
|
+
characterProfile: { user: 2, app: 2, dna: 1, thread: 2 },
|
|
468
|
+
placeholders: { user: 3, app: 3, dna: 2, thread: 3 }
|
|
469
|
+
},
|
|
470
|
+
depth: 2,
|
|
471
|
+
model: {
|
|
472
|
+
modelId: "deepseek/deepseek-v3.2",
|
|
473
|
+
inputPrice: 0.28,
|
|
474
|
+
outputPrice: 0.4,
|
|
475
|
+
hasTools: true,
|
|
476
|
+
canAnalyze: false,
|
|
477
|
+
reason: "Rich context"
|
|
478
|
+
},
|
|
479
|
+
reasoning: ["Rich preset"]
|
|
480
|
+
},
|
|
481
|
+
/** Admin/Sato mode - maximum user context */
|
|
482
|
+
admin: {
|
|
483
|
+
join: {
|
|
484
|
+
memories: { user: 15, app: 5, dna: 3, thread: 8 },
|
|
485
|
+
instructions: { user: 10, app: 4, dna: 2, thread: 5 },
|
|
486
|
+
characterProfile: { user: 3, app: 2, dna: 1, thread: 2 },
|
|
487
|
+
placeholders: { user: 5, app: 3, dna: 2, thread: 4 }
|
|
488
|
+
},
|
|
489
|
+
depth: 2,
|
|
490
|
+
model: {
|
|
491
|
+
modelId: "anthropic/claude-sonnet-4-6",
|
|
492
|
+
inputPrice: 3,
|
|
493
|
+
outputPrice: 15,
|
|
494
|
+
hasTools: true,
|
|
495
|
+
canAnalyze: true,
|
|
496
|
+
reason: "Admin mode: maximum context for Sato reports"
|
|
497
|
+
},
|
|
498
|
+
reasoning: ["Admin preset: Sato mode activated"]
|
|
499
|
+
},
|
|
500
|
+
kanban: {
|
|
501
|
+
join: {
|
|
502
|
+
memories: { user: 4, app: 6, dna: 2, thread: 3 },
|
|
503
|
+
instructions: { user: 3, app: 6, dna: 1, thread: 3 },
|
|
504
|
+
characterProfile: { user: 1, app: 2, dna: 1, thread: 1 },
|
|
505
|
+
placeholders: { user: 2, app: 4, dna: 1, thread: 2 }
|
|
506
|
+
},
|
|
507
|
+
depth: 1,
|
|
508
|
+
model: {
|
|
509
|
+
modelId: "deepseek/deepseek-chat",
|
|
510
|
+
inputPrice: 0.15,
|
|
511
|
+
outputPrice: 0.45,
|
|
512
|
+
hasTools: true,
|
|
513
|
+
canAnalyze: false,
|
|
514
|
+
reason: "Kanban needs tools"
|
|
515
|
+
},
|
|
516
|
+
reasoning: ["Kanban preset"]
|
|
517
|
+
},
|
|
518
|
+
tribe: {
|
|
519
|
+
join: {
|
|
520
|
+
memories: { user: 5, app: 3, dna: 2, thread: 8 },
|
|
521
|
+
instructions: { user: 4, app: 3, dna: 1, thread: 6 },
|
|
522
|
+
characterProfile: { user: 2, app: 2, dna: 1, thread: 2 },
|
|
523
|
+
placeholders: { user: 3, app: 3, dna: 1, thread: 4 }
|
|
524
|
+
},
|
|
525
|
+
depth: 2,
|
|
526
|
+
model: {
|
|
527
|
+
modelId: "deepseek/deepseek-v3.2",
|
|
528
|
+
inputPrice: 0.28,
|
|
529
|
+
outputPrice: 0.4,
|
|
530
|
+
hasTools: true,
|
|
531
|
+
canAnalyze: false,
|
|
532
|
+
reason: "Tribe needs thread context"
|
|
533
|
+
},
|
|
534
|
+
reasoning: ["Tribe preset"]
|
|
535
|
+
},
|
|
536
|
+
retro: {
|
|
537
|
+
join: {
|
|
538
|
+
memories: { user: 8, app: 2, dna: 1, thread: 5 },
|
|
539
|
+
instructions: { user: 6, app: 2, dna: 1, thread: 4 },
|
|
540
|
+
characterProfile: { user: 3, app: 1, dna: 0, thread: 2 },
|
|
541
|
+
placeholders: { user: 4, app: 2, dna: 1, thread: 3 }
|
|
542
|
+
},
|
|
543
|
+
depth: 1,
|
|
544
|
+
model: {
|
|
545
|
+
modelId: "anthropic/claude-sonnet-4-6",
|
|
546
|
+
inputPrice: 3,
|
|
547
|
+
outputPrice: 15,
|
|
548
|
+
hasTools: true,
|
|
549
|
+
canAnalyze: true,
|
|
550
|
+
reason: "Retro benefits from quality"
|
|
551
|
+
},
|
|
552
|
+
reasoning: ["Retro preset"]
|
|
553
|
+
},
|
|
554
|
+
background: {
|
|
555
|
+
join: {
|
|
556
|
+
memories: { user: 8, app: 5, dna: 3, thread: 6 },
|
|
557
|
+
instructions: { user: 5, app: 4, dna: 2, thread: 4 },
|
|
558
|
+
characterProfile: { user: 2, app: 2, dna: 1, thread: 2 },
|
|
559
|
+
placeholders: { user: 3, app: 3, dna: 2, thread: 3 }
|
|
560
|
+
},
|
|
561
|
+
depth: 2,
|
|
562
|
+
model: {
|
|
563
|
+
modelId: "deepseek/deepseek-v3.2",
|
|
564
|
+
inputPrice: 0.28,
|
|
565
|
+
outputPrice: 0.4,
|
|
566
|
+
hasTools: true,
|
|
567
|
+
canAnalyze: false,
|
|
568
|
+
reason: "Background job: more context"
|
|
569
|
+
},
|
|
570
|
+
reasoning: ["Background preset"]
|
|
571
|
+
},
|
|
572
|
+
free: {
|
|
573
|
+
join: {
|
|
574
|
+
memories: { user: 2, app: 1, dna: 0, thread: 2 },
|
|
575
|
+
instructions: { user: 1, app: 1, dna: 0, thread: 1 },
|
|
576
|
+
characterProfile: { user: 0, app: 0, dna: 0, thread: 0 },
|
|
577
|
+
placeholders: { user: 1, app: 1, dna: 0, thread: 1 }
|
|
578
|
+
},
|
|
579
|
+
depth: 0,
|
|
580
|
+
model: {
|
|
581
|
+
modelId: "nvidia/nemotron-3-super-120b-a12b:free",
|
|
582
|
+
inputPrice: 0,
|
|
583
|
+
outputPrice: 0,
|
|
584
|
+
hasTools: true,
|
|
585
|
+
canAnalyze: false,
|
|
586
|
+
reason: "Zero cost"
|
|
587
|
+
},
|
|
588
|
+
reasoning: ["Free preset"]
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
function swapModel(modelId, preferFree) {
|
|
592
|
+
return { modelId, swapped: false };
|
|
593
|
+
}
|
|
594
|
+
function optimizeChopStick(ctx) {
|
|
595
|
+
const reasoning = [];
|
|
596
|
+
let base = presets.balanced;
|
|
597
|
+
if (ctx.isAdmin || ctx.isSatoMode) {
|
|
598
|
+
base = presets.admin;
|
|
599
|
+
reasoning.push("Admin/Sato mode: maximum user context");
|
|
600
|
+
} else if (ctx.isBackgroundJob) {
|
|
601
|
+
base = presets.background;
|
|
602
|
+
} else if (ctx.hasRetro) {
|
|
603
|
+
base = presets.retro;
|
|
604
|
+
} else if (ctx.appType === "kanban" || ctx.hasKanban) {
|
|
605
|
+
base = presets.kanban;
|
|
606
|
+
} else if (ctx.appType === "tribe") {
|
|
607
|
+
base = presets.tribe;
|
|
608
|
+
}
|
|
609
|
+
if ((ctx.creditsLeft ?? 10) < 3) {
|
|
610
|
+
base = presets.free;
|
|
611
|
+
reasoning.push(`Low credits: ${ctx.creditsLeft}`);
|
|
612
|
+
}
|
|
613
|
+
let depth = base.depth;
|
|
614
|
+
if ((ctx.messageCount ?? 0) > 50) {
|
|
615
|
+
depth = 2;
|
|
616
|
+
reasoning.push(`Deep thread: ${ctx.messageCount}`);
|
|
617
|
+
}
|
|
618
|
+
const join = { ...base.join };
|
|
619
|
+
if (ctx.hasDNA) {
|
|
620
|
+
join.memories.dna = Math.min(5, join.memories.dna + 2);
|
|
621
|
+
join.instructions.dna = Math.min(3, join.instructions.dna + 1);
|
|
622
|
+
reasoning.push("DNA boost");
|
|
623
|
+
}
|
|
624
|
+
if (ctx.hasTimer) {
|
|
625
|
+
join.memories.app = Math.min(10, join.memories.app + 1);
|
|
626
|
+
reasoning.push("Timer boost");
|
|
627
|
+
}
|
|
628
|
+
let modelId = ctx.defaultModelId || base.model.modelId;
|
|
629
|
+
if (ctx.needsTools && !modelPricing[modelId]?.tools) {
|
|
630
|
+
modelId = "deepseek/deepseek-chat";
|
|
631
|
+
reasoning.push("Tool requirement");
|
|
632
|
+
}
|
|
633
|
+
if (ctx.needsAnalysis && !modelPricing[modelId]?.analyze) {
|
|
634
|
+
modelId = "anthropic/claude-sonnet-4-6";
|
|
635
|
+
reasoning.push("Analysis requirement");
|
|
636
|
+
}
|
|
637
|
+
if (ctx.allowsModelSwap) {
|
|
638
|
+
swapModel(
|
|
639
|
+
modelId,
|
|
640
|
+
ctx.preferFree || (ctx.creditsLeft ?? 10) < 5
|
|
641
|
+
);
|
|
642
|
+
}
|
|
643
|
+
const pricing = modelPricing[modelId];
|
|
644
|
+
return {
|
|
645
|
+
join,
|
|
646
|
+
depth,
|
|
647
|
+
model: {
|
|
648
|
+
modelId,
|
|
649
|
+
inputPrice: pricing?.input ?? 1,
|
|
650
|
+
outputPrice: pricing?.output ?? 2,
|
|
651
|
+
hasTools: pricing?.tools ?? true,
|
|
652
|
+
canAnalyze: pricing?.analyze ?? false,
|
|
653
|
+
reason: reasoning.join(", ") || "Default"
|
|
654
|
+
},
|
|
655
|
+
reasoning: [...base.reasoning, ...reasoning]
|
|
656
|
+
};
|
|
657
|
+
}
|
|
658
|
+
function buildStoreKnowledgeBase(ctx) {
|
|
659
|
+
const reasoning = [];
|
|
660
|
+
const mainConfig = optimizeChopStick({
|
|
661
|
+
appType: ctx.appType,
|
|
662
|
+
hasDNA: ctx.hasDNA,
|
|
663
|
+
hasTimer: ctx.hasTimer,
|
|
664
|
+
hasKanban: ctx.hasKanban,
|
|
665
|
+
messageCount: ctx.messageCount,
|
|
666
|
+
isBackgroundJob: ctx.isBackgroundJob
|
|
667
|
+
});
|
|
668
|
+
const contextConfig = optimizeChopStick({
|
|
669
|
+
appType: "default",
|
|
670
|
+
isBackgroundJob: true
|
|
671
|
+
// lighter
|
|
672
|
+
});
|
|
673
|
+
const apps = ctx.storeAppIds.map((id, index) => {
|
|
674
|
+
const isMain = id === ctx.mainAppId;
|
|
675
|
+
const config2 = isMain ? mainConfig : contextConfig;
|
|
676
|
+
const limits = isMain ? { memories: 15, instructions: 10, messages: 10 } : { memories: 5, instructions: 3, messages: 3 };
|
|
677
|
+
return {
|
|
678
|
+
app: {
|
|
679
|
+
id,
|
|
680
|
+
name: `App-${index + 1}`,
|
|
681
|
+
// Caller doldurur
|
|
682
|
+
slug: `app-${id.slice(0, 6)}`
|
|
683
|
+
},
|
|
684
|
+
context: {
|
|
685
|
+
join: config2.join,
|
|
686
|
+
depth: config2.depth,
|
|
687
|
+
isMainApp: isMain
|
|
688
|
+
},
|
|
689
|
+
limits
|
|
690
|
+
};
|
|
691
|
+
});
|
|
692
|
+
const mainApp = apps.find((a) => a.app.id === ctx.mainAppId) || apps[0];
|
|
693
|
+
const contextApps = apps.filter((a) => a.app.id !== ctx.mainAppId);
|
|
694
|
+
const estimatedTokens = apps.reduce((sum, app) => {
|
|
695
|
+
const memTokens = app.limits.memories * 100;
|
|
696
|
+
const instTokens = app.limits.instructions * 200;
|
|
697
|
+
const msgTokens = app.limits.messages * 150;
|
|
698
|
+
return sum + memTokens + instTokens + msgTokens;
|
|
699
|
+
}, 0);
|
|
700
|
+
if (ctx.hasDNA) reasoning.push("DNA context included");
|
|
701
|
+
if (ctx.hasTimer) reasoning.push("Timer context included");
|
|
702
|
+
if (ctx.hasKanban) reasoning.push("Kanban context included");
|
|
703
|
+
return {
|
|
704
|
+
apps,
|
|
705
|
+
mainApp,
|
|
706
|
+
contextApps,
|
|
707
|
+
estimatedTokens,
|
|
708
|
+
meta: {
|
|
709
|
+
totalApps: apps.length,
|
|
710
|
+
reasoning,
|
|
711
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
712
|
+
}
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
function getPreset(name) {
|
|
716
|
+
return presets[name] ?? presets.balanced;
|
|
717
|
+
}
|
|
718
|
+
function getJoinWeights(ctx) {
|
|
719
|
+
return optimizeChopStick(ctx).join;
|
|
720
|
+
}
|
|
721
|
+
function buildRamenPayload(base, ctx) {
|
|
722
|
+
const opt = optimizeChopStick(ctx);
|
|
723
|
+
const estimatedCost = 2 * (opt.model.inputPrice + opt.model.outputPrice);
|
|
724
|
+
return {
|
|
725
|
+
...base,
|
|
726
|
+
join: opt.join,
|
|
727
|
+
depth: opt.depth,
|
|
728
|
+
_meta: {
|
|
729
|
+
modelId: opt.model.modelId,
|
|
730
|
+
estimatedCost: Math.round(estimatedCost * 1e3) / 1e3,
|
|
731
|
+
reasoning: opt.reasoning
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
// src/agent/goldenRatio.ts
|
|
737
|
+
var FIBONACCI = [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144];
|
|
738
|
+
var DEFAULT_TRIGGERS = [
|
|
739
|
+
{
|
|
740
|
+
feature: "memory",
|
|
741
|
+
homeApp: "hippo",
|
|
742
|
+
threadThreshold: 3,
|
|
743
|
+
messageThreshold: 2
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
feature: "kanban",
|
|
747
|
+
homeApp: "focus",
|
|
748
|
+
threadThreshold: 5,
|
|
749
|
+
messageThreshold: 3
|
|
750
|
+
},
|
|
751
|
+
{
|
|
752
|
+
feature: "characterProfile",
|
|
753
|
+
homeApp: "hippo",
|
|
754
|
+
threadThreshold: 5,
|
|
755
|
+
messageThreshold: 5
|
|
756
|
+
},
|
|
757
|
+
{
|
|
758
|
+
feature: "placeholders",
|
|
759
|
+
homeApp: "hippo",
|
|
760
|
+
threadThreshold: 8,
|
|
761
|
+
messageThreshold: 5
|
|
762
|
+
},
|
|
763
|
+
{
|
|
764
|
+
feature: "instructions",
|
|
765
|
+
homeApp: "sushi",
|
|
766
|
+
threadThreshold: 8,
|
|
767
|
+
messageThreshold: 8
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
feature: "vectorEmbed",
|
|
771
|
+
homeApp: "grape",
|
|
772
|
+
threadThreshold: 13,
|
|
773
|
+
messageThreshold: 8
|
|
774
|
+
}
|
|
775
|
+
];
|
|
776
|
+
function getDefaultTriggers() {
|
|
777
|
+
return DEFAULT_TRIGGERS.map((t) => ({ ...t }));
|
|
778
|
+
}
|
|
779
|
+
function getUserGoldenRatioConfig(userConfig) {
|
|
780
|
+
const defaults = Object.fromEntries(
|
|
781
|
+
DEFAULT_TRIGGERS.map((t) => [
|
|
782
|
+
t.feature,
|
|
783
|
+
{
|
|
784
|
+
threadThreshold: t.threadThreshold,
|
|
785
|
+
messageThreshold: t.messageThreshold,
|
|
786
|
+
enabled: true
|
|
787
|
+
}
|
|
788
|
+
])
|
|
789
|
+
);
|
|
790
|
+
if (!userConfig) return defaults;
|
|
791
|
+
for (const key of Object.keys(userConfig)) {
|
|
792
|
+
const cfg = userConfig[key];
|
|
793
|
+
if (!cfg) continue;
|
|
794
|
+
defaults[key] = {
|
|
795
|
+
threadThreshold: cfg.threadThreshold ?? defaults[key].threadThreshold,
|
|
796
|
+
messageThreshold: cfg.messageThreshold ?? defaults[key].messageThreshold,
|
|
797
|
+
enabled: cfg.enabled ?? true
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
return defaults;
|
|
801
|
+
}
|
|
802
|
+
function evaluateGoldenRatio(userThreadCount, threadMessageCount, lastTriggeredFeatures, userConfig) {
|
|
803
|
+
const config2 = getUserGoldenRatioConfig(userConfig);
|
|
804
|
+
const triggeredSet = new Set(lastTriggeredFeatures);
|
|
805
|
+
return DEFAULT_TRIGGERS.map((trigger) => {
|
|
806
|
+
const cfg = config2[trigger.feature];
|
|
807
|
+
const isTriggered = cfg.enabled && userThreadCount >= cfg.threadThreshold && threadMessageCount >= cfg.messageThreshold;
|
|
808
|
+
return {
|
|
809
|
+
feature: trigger.feature,
|
|
810
|
+
homeApp: trigger.homeApp,
|
|
811
|
+
triggered: isTriggered,
|
|
812
|
+
alreadyTriggered: triggeredSet.has(trigger.feature),
|
|
813
|
+
threadThreshold: cfg.threadThreshold,
|
|
814
|
+
messageThreshold: cfg.messageThreshold,
|
|
815
|
+
userThreadCount,
|
|
816
|
+
threadMessageCount
|
|
817
|
+
};
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
function getNewlyTriggeredFeatures(userThreadCount, threadMessageCount, lastTriggeredFeatures, userConfig) {
|
|
821
|
+
return evaluateGoldenRatio(
|
|
822
|
+
userThreadCount,
|
|
823
|
+
threadMessageCount,
|
|
824
|
+
lastTriggeredFeatures,
|
|
825
|
+
userConfig
|
|
826
|
+
).filter((e) => e.triggered && !e.alreadyTriggered);
|
|
827
|
+
}
|
|
828
|
+
function getNextFibonacciThreshold(value) {
|
|
829
|
+
const next = FIBONACCI.find((f) => f > value);
|
|
830
|
+
return next ?? FIBONACCI[FIBONACCI.length - 1];
|
|
831
|
+
}
|
|
832
|
+
function formatFibonacciPreview(userThreadCount, threadMessageCount, userConfig) {
|
|
833
|
+
const config2 = getUserGoldenRatioConfig(userConfig);
|
|
834
|
+
return DEFAULT_TRIGGERS.map((trigger) => {
|
|
835
|
+
const cfg = config2[trigger.feature];
|
|
836
|
+
const ready = cfg.enabled && userThreadCount >= cfg.threadThreshold && threadMessageCount >= cfg.messageThreshold;
|
|
837
|
+
return {
|
|
838
|
+
feature: trigger.feature,
|
|
839
|
+
homeApp: trigger.homeApp,
|
|
840
|
+
progressThread: Math.min(1, userThreadCount / cfg.threadThreshold),
|
|
841
|
+
progressMessage: Math.min(1, threadMessageCount / cfg.messageThreshold),
|
|
842
|
+
ready,
|
|
843
|
+
nextThresholdThread: cfg.threadThreshold,
|
|
844
|
+
nextThresholdMessage: cfg.messageThreshold
|
|
845
|
+
};
|
|
846
|
+
});
|
|
847
|
+
}
|
|
143
848
|
|
|
144
849
|
// src/index.ts
|
|
145
850
|
dotenv__namespace.config();
|
|
@@ -253,6 +958,8 @@ var log = ({ page }) => {
|
|
|
253
958
|
};
|
|
254
959
|
|
|
255
960
|
exports.APIClient = APIClient;
|
|
961
|
+
exports.DEFAULT_TRIGGERS = DEFAULT_TRIGGERS;
|
|
962
|
+
exports.FIBONACCI = FIBONACCI;
|
|
256
963
|
exports.TEST_GUEST_FINGERPRINTS = TEST_GUEST_FINGERPRINTS;
|
|
257
964
|
exports.TEST_MEMBER_EMAILS = TEST_MEMBER_EMAILS;
|
|
258
965
|
exports.TEST_MEMBER_FINGERPRINTS = TEST_MEMBER_FINGERPRINTS;
|
|
@@ -273,15 +980,42 @@ exports.VEX_TEST_PASSWORD = VEX_TEST_PASSWORD;
|
|
|
273
980
|
exports.VEX_TEST_PASSWORD_2 = VEX_TEST_PASSWORD_2;
|
|
274
981
|
exports.VEX_TEST_PASSWORD_3 = VEX_TEST_PASSWORD_3;
|
|
275
982
|
exports.VEX_TEST_PASSWORD_4 = VEX_TEST_PASSWORD_4;
|
|
983
|
+
exports.autoDetectAndSwitch = autoDetectAndSwitch;
|
|
984
|
+
exports.autoDetectAndSwitchSafe = autoDetectAndSwitchSafe;
|
|
985
|
+
exports.buildRamenPayload = buildRamenPayload;
|
|
986
|
+
exports.buildStoreKnowledgeBase = buildStoreKnowledgeBase;
|
|
276
987
|
exports.capitalizeFirstLetter = capitalizeFirstLetter;
|
|
988
|
+
exports.createBranchWorkspace = createBranchWorkspace;
|
|
989
|
+
exports.deleteBranchWorkspace = deleteBranchWorkspace;
|
|
990
|
+
exports.evaluateGoldenRatio = evaluateGoldenRatio;
|
|
991
|
+
exports.formatFibonacciPreview = formatFibonacciPreview;
|
|
992
|
+
exports.generateAgentId = generateAgentId;
|
|
993
|
+
exports.getCurrentBranch = getCurrentBranch;
|
|
994
|
+
exports.getCurrentBranchSafe = getCurrentBranchSafe;
|
|
995
|
+
exports.getDefaultTriggers = getDefaultTriggers;
|
|
996
|
+
exports.getJoinWeights = getJoinWeights;
|
|
277
997
|
exports.getModelCredits = getModelCredits;
|
|
998
|
+
exports.getNewlyTriggeredFeatures = getNewlyTriggeredFeatures;
|
|
999
|
+
exports.getNextFibonacciThreshold = getNextFibonacciThreshold;
|
|
1000
|
+
exports.getOrCreateBranchWorkspace = getOrCreateBranchWorkspace;
|
|
1001
|
+
exports.getPreset = getPreset;
|
|
278
1002
|
exports.getURL = getURL;
|
|
1003
|
+
exports.getUserGoldenRatioConfig = getUserGoldenRatioConfig;
|
|
279
1004
|
exports.isCI = isCI;
|
|
1005
|
+
exports.loadBranchWorkspace = loadBranchWorkspace;
|
|
280
1006
|
exports.log = log;
|
|
1007
|
+
exports.modelPricing = modelPricing;
|
|
1008
|
+
exports.optimizeChopStick = optimizeChopStick;
|
|
1009
|
+
exports.parseBranchName = parseBranchName;
|
|
1010
|
+
exports.presets = presets;
|
|
1011
|
+
exports.recordMutation = recordMutation;
|
|
1012
|
+
exports.saveBranchWorkspace = saveBranchWorkspace;
|
|
281
1013
|
exports.scheduledJobFactory = scheduledJobFactory;
|
|
282
1014
|
exports.simulateInputPaste = simulateInputPaste;
|
|
283
1015
|
exports.simulatePaste = simulatePaste;
|
|
284
1016
|
exports.storeApps = storeApps;
|
|
1017
|
+
exports.switchBranchContext = switchBranchContext;
|
|
1018
|
+
exports.switchBranchContextSafe = switchBranchContextSafe;
|
|
285
1019
|
exports.wait = wait;
|
|
286
1020
|
//# sourceMappingURL=index.js.map
|
|
287
1021
|
//# sourceMappingURL=index.js.map
|