aura-code 0.3.0
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/LICENSE +21 -0
- package/README.md +137 -0
- package/dist/agent/context.d.ts +13 -0
- package/dist/agent/context.js +183 -0
- package/dist/agent/context.js.map +1 -0
- package/dist/agent/loop.d.ts +60 -0
- package/dist/agent/loop.js +228 -0
- package/dist/agent/loop.js.map +1 -0
- package/dist/agent/session-store.d.ts +30 -0
- package/dist/agent/session-store.js +178 -0
- package/dist/agent/session-store.js.map +1 -0
- package/dist/agent/spawner.d.ts +57 -0
- package/dist/agent/spawner.js +112 -0
- package/dist/agent/spawner.js.map +1 -0
- package/dist/agent/system-prompt.d.ts +3 -0
- package/dist/agent/system-prompt.js +100 -0
- package/dist/agent/system-prompt.js.map +1 -0
- package/dist/architect/engine.d.ts +47 -0
- package/dist/architect/engine.js +217 -0
- package/dist/architect/engine.js.map +1 -0
- package/dist/architect/types.d.ts +61 -0
- package/dist/architect/types.js +6 -0
- package/dist/architect/types.js.map +1 -0
- package/dist/cli/diamond.d.ts +1 -0
- package/dist/cli/diamond.js +23 -0
- package/dist/cli/diamond.js.map +1 -0
- package/dist/cli/display.d.ts +44 -0
- package/dist/cli/display.js +234 -0
- package/dist/cli/display.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +1734 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/defaults.d.ts +46 -0
- package/dist/config/defaults.js +106 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/project-config.d.ts +90 -0
- package/dist/config/project-config.js +141 -0
- package/dist/config/project-config.js.map +1 -0
- package/dist/harness/proposer.d.ts +26 -0
- package/dist/harness/proposer.js +204 -0
- package/dist/harness/proposer.js.map +1 -0
- package/dist/harness/weakness-miner.d.ts +28 -0
- package/dist/harness/weakness-miner.js +359 -0
- package/dist/harness/weakness-miner.js.map +1 -0
- package/dist/integrations/harnesses.d.ts +23 -0
- package/dist/integrations/harnesses.js +161 -0
- package/dist/integrations/harnesses.js.map +1 -0
- package/dist/orchestration/competence.d.ts +53 -0
- package/dist/orchestration/competence.js +181 -0
- package/dist/orchestration/competence.js.map +1 -0
- package/dist/orchestration/executor.d.ts +42 -0
- package/dist/orchestration/executor.js +206 -0
- package/dist/orchestration/executor.js.map +1 -0
- package/dist/orchestration/index.d.ts +20 -0
- package/dist/orchestration/index.js +39 -0
- package/dist/orchestration/index.js.map +1 -0
- package/dist/orchestration/orchestrator-prompts.d.ts +11 -0
- package/dist/orchestration/orchestrator-prompts.js +153 -0
- package/dist/orchestration/orchestrator-prompts.js.map +1 -0
- package/dist/orchestration/orchestrator.d.ts +27 -0
- package/dist/orchestration/orchestrator.js +169 -0
- package/dist/orchestration/orchestrator.js.map +1 -0
- package/dist/orchestration/plan-store.d.ts +53 -0
- package/dist/orchestration/plan-store.js +176 -0
- package/dist/orchestration/plan-store.js.map +1 -0
- package/dist/orchestration/router-prompts.d.ts +6 -0
- package/dist/orchestration/router-prompts.js +55 -0
- package/dist/orchestration/router-prompts.js.map +1 -0
- package/dist/orchestration/router.d.ts +23 -0
- package/dist/orchestration/router.js +70 -0
- package/dist/orchestration/router.js.map +1 -0
- package/dist/orchestration/ruby-detect.d.ts +6 -0
- package/dist/orchestration/ruby-detect.js +130 -0
- package/dist/orchestration/ruby-detect.js.map +1 -0
- package/dist/orchestration/ruby-types.d.ts +44 -0
- package/dist/orchestration/ruby-types.js +6 -0
- package/dist/orchestration/ruby-types.js.map +1 -0
- package/dist/orchestration/specialist-prompts.d.ts +19 -0
- package/dist/orchestration/specialist-prompts.js +143 -0
- package/dist/orchestration/specialist-prompts.js.map +1 -0
- package/dist/orchestration/specialists.d.ts +66 -0
- package/dist/orchestration/specialists.js +175 -0
- package/dist/orchestration/specialists.js.map +1 -0
- package/dist/orchestration/types.d.ts +82 -0
- package/dist/orchestration/types.js +6 -0
- package/dist/orchestration/types.js.map +1 -0
- package/dist/perception/extractor.d.ts +7 -0
- package/dist/perception/extractor.js +521 -0
- package/dist/perception/extractor.js.map +1 -0
- package/dist/perception/graph-store.d.ts +25 -0
- package/dist/perception/graph-store.js +117 -0
- package/dist/perception/graph-store.js.map +1 -0
- package/dist/perception/index.d.ts +4 -0
- package/dist/perception/index.js +18 -0
- package/dist/perception/index.js.map +1 -0
- package/dist/perception/queries.d.ts +29 -0
- package/dist/perception/queries.js +354 -0
- package/dist/perception/queries.js.map +1 -0
- package/dist/perception/types.d.ts +103 -0
- package/dist/perception/types.js +6 -0
- package/dist/perception/types.js.map +1 -0
- package/dist/providers/anthropic.d.ts +11 -0
- package/dist/providers/anthropic.js +172 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/factory.d.ts +58 -0
- package/dist/providers/factory.js +354 -0
- package/dist/providers/factory.js.map +1 -0
- package/dist/providers/fallback.d.ts +24 -0
- package/dist/providers/fallback.js +72 -0
- package/dist/providers/fallback.js.map +1 -0
- package/dist/providers/google.d.ts +11 -0
- package/dist/providers/google.js +129 -0
- package/dist/providers/google.js.map +1 -0
- package/dist/providers/openai-compatible.d.ts +24 -0
- package/dist/providers/openai-compatible.js +216 -0
- package/dist/providers/openai-compatible.js.map +1 -0
- package/dist/providers/resilient-factory.d.ts +24 -0
- package/dist/providers/resilient-factory.js +57 -0
- package/dist/providers/resilient-factory.js.map +1 -0
- package/dist/providers/resilient.d.ts +63 -0
- package/dist/providers/resilient.js +145 -0
- package/dist/providers/resilient.js.map +1 -0
- package/dist/providers/types.d.ts +84 -0
- package/dist/providers/types.js +6 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/ruby/alternator.d.ts +40 -0
- package/dist/ruby/alternator.js +233 -0
- package/dist/ruby/alternator.js.map +1 -0
- package/dist/ruby/competence.d.ts +34 -0
- package/dist/ruby/competence.js +264 -0
- package/dist/ruby/competence.js.map +1 -0
- package/dist/ruby/episode-capture.d.ts +56 -0
- package/dist/ruby/episode-capture.js +193 -0
- package/dist/ruby/episode-capture.js.map +1 -0
- package/dist/ruby/fine-tune.d.ts +16 -0
- package/dist/ruby/fine-tune.js +253 -0
- package/dist/ruby/fine-tune.js.map +1 -0
- package/dist/ruby/index.d.ts +10 -0
- package/dist/ruby/index.js +26 -0
- package/dist/ruby/index.js.map +1 -0
- package/dist/ruby/ruby-model.d.ts +36 -0
- package/dist/ruby/ruby-model.js +81 -0
- package/dist/ruby/ruby-model.js.map +1 -0
- package/dist/ruby/training-data.d.ts +11 -0
- package/dist/ruby/training-data.js +107 -0
- package/dist/ruby/training-data.js.map +1 -0
- package/dist/ruby/types.d.ts +136 -0
- package/dist/ruby/types.js +20 -0
- package/dist/ruby/types.js.map +1 -0
- package/dist/safety/permissions.d.ts +32 -0
- package/dist/safety/permissions.js +304 -0
- package/dist/safety/permissions.js.map +1 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.js +342 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/session.d.ts +22 -0
- package/dist/server/session.js +16 -0
- package/dist/server/session.js.map +1 -0
- package/dist/setup/first-run.d.ts +41 -0
- package/dist/setup/first-run.js +386 -0
- package/dist/setup/first-run.js.map +1 -0
- package/dist/setup/global-config.d.ts +19 -0
- package/dist/setup/global-config.js +97 -0
- package/dist/setup/global-config.js.map +1 -0
- package/dist/tools/audio-transcribe.d.ts +8 -0
- package/dist/tools/audio-transcribe.js +156 -0
- package/dist/tools/audio-transcribe.js.map +1 -0
- package/dist/tools/browser.d.ts +15 -0
- package/dist/tools/browser.js +241 -0
- package/dist/tools/browser.js.map +1 -0
- package/dist/tools/calendar.d.ts +12 -0
- package/dist/tools/calendar.js +196 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/clipboard.d.ts +7 -0
- package/dist/tools/clipboard.js +90 -0
- package/dist/tools/clipboard.js.map +1 -0
- package/dist/tools/cron.d.ts +10 -0
- package/dist/tools/cron.js +167 -0
- package/dist/tools/cron.js.map +1 -0
- package/dist/tools/edit-file.d.ts +6 -0
- package/dist/tools/edit-file.js +98 -0
- package/dist/tools/edit-file.js.map +1 -0
- package/dist/tools/email.d.ts +11 -0
- package/dist/tools/email.js +153 -0
- package/dist/tools/email.js.map +1 -0
- package/dist/tools/git.d.ts +1 -0
- package/dist/tools/git.js +7 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/http-request.d.ts +12 -0
- package/dist/tools/http-request.js +91 -0
- package/dist/tools/http-request.js.map +1 -0
- package/dist/tools/image-read.d.ts +7 -0
- package/dist/tools/image-read.js +125 -0
- package/dist/tools/image-read.js.map +1 -0
- package/dist/tools/index.d.ts +3 -0
- package/dist/tools/index.js +201 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-dir.d.ts +1 -0
- package/dist/tools/list-dir.js +6 -0
- package/dist/tools/list-dir.js.map +1 -0
- package/dist/tools/mcp.d.ts +11 -0
- package/dist/tools/mcp.js +356 -0
- package/dist/tools/mcp.js.map +1 -0
- package/dist/tools/memory.d.ts +9 -0
- package/dist/tools/memory.js +124 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/notify.d.ts +9 -0
- package/dist/tools/notify.js +40 -0
- package/dist/tools/notify.js.map +1 -0
- package/dist/tools/read-file.d.ts +6 -0
- package/dist/tools/read-file.js +76 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/run-shell.d.ts +1 -0
- package/dist/tools/run-shell.js +6 -0
- package/dist/tools/run-shell.js.map +1 -0
- package/dist/tools/run-tests.d.ts +1 -0
- package/dist/tools/run-tests.js +6 -0
- package/dist/tools/run-tests.js.map +1 -0
- package/dist/tools/search-code.d.ts +1 -0
- package/dist/tools/search-code.js +6 -0
- package/dist/tools/search-code.js.map +1 -0
- package/dist/tools/telegram-bot.d.ts +2 -0
- package/dist/tools/telegram-bot.js +693 -0
- package/dist/tools/telegram-bot.js.map +1 -0
- package/dist/tools/telegram-safety.d.ts +52 -0
- package/dist/tools/telegram-safety.js +189 -0
- package/dist/tools/telegram-safety.js.map +1 -0
- package/dist/tools/telegram.d.ts +16 -0
- package/dist/tools/telegram.js +227 -0
- package/dist/tools/telegram.js.map +1 -0
- package/dist/tools/tools.d.ts +48 -0
- package/dist/tools/tools.js +328 -0
- package/dist/tools/tools.js.map +1 -0
- package/dist/tools/web-fetch.d.ts +11 -0
- package/dist/tools/web-fetch.js +119 -0
- package/dist/tools/web-fetch.js.map +1 -0
- package/dist/tools/web-search.d.ts +8 -0
- package/dist/tools/web-search.js +81 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tools/whatsapp.d.ts +10 -0
- package/dist/tools/whatsapp.js +222 -0
- package/dist/tools/whatsapp.js.map +1 -0
- package/dist/tools/write-file.d.ts +1 -0
- package/dist/tools/write-file.js +6 -0
- package/dist/tools/write-file.js.map +1 -0
- package/dist/tools/youtube-transcript.d.ts +9 -0
- package/dist/tools/youtube-transcript.js +200 -0
- package/dist/tools/youtube-transcript.js.map +1 -0
- package/dist/util/circuit-breaker.d.ts +44 -0
- package/dist/util/circuit-breaker.js +78 -0
- package/dist/util/circuit-breaker.js.map +1 -0
- package/dist/util/env.d.ts +18 -0
- package/dist/util/env.js +39 -0
- package/dist/util/env.js.map +1 -0
- package/dist/util/errors.d.ts +42 -0
- package/dist/util/errors.js +121 -0
- package/dist/util/errors.js.map +1 -0
- package/dist/util/rate-limiter.d.ts +71 -0
- package/dist/util/rate-limiter.js +141 -0
- package/dist/util/rate-limiter.js.map +1 -0
- package/dist/util/retry.d.ts +30 -0
- package/dist/util/retry.js +57 -0
- package/dist/util/retry.js.map +1 -0
- package/dist/util/sanitize.d.ts +16 -0
- package/dist/util/sanitize.js +255 -0
- package/dist/util/sanitize.js.map +1 -0
- package/dist/verify/checks.d.ts +21 -0
- package/dist/verify/checks.js +311 -0
- package/dist/verify/checks.js.map +1 -0
- package/dist/verify/index.d.ts +33 -0
- package/dist/verify/index.js +127 -0
- package/dist/verify/index.js.map +1 -0
- package/dist/verify/types.d.ts +20 -0
- package/dist/verify/types.js +3 -0
- package/dist/verify/types.js.map +1 -0
- package/dist/versioncheck.d.ts +22 -0
- package/dist/versioncheck.js +203 -0
- package/dist/versioncheck.js.map +1 -0
- package/dist/viz/index.d.ts +2 -0
- package/dist/viz/index.js +733 -0
- package/dist/viz/index.js.map +1 -0
- package/dist/workflows/engine.d.ts +46 -0
- package/dist/workflows/engine.js +320 -0
- package/dist/workflows/engine.js.map +1 -0
- package/dist/workflows/types.d.ts +92 -0
- package/dist/workflows/types.js +6 -0
- package/dist/workflows/types.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getEpisodeStats = exports.deleteEpisode = exports.loadEpisodes = exports.saveEpisode = exports.episodeStore = void 0;
|
|
37
|
+
exports.estimateTokens = estimateTokens;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const competence_js_1 = require("./competence.js");
|
|
41
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
42
|
+
// Episode persistence
|
|
43
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
44
|
+
//
|
|
45
|
+
// Stores alternation episodes under ~/.aura/episodes/{projectHash}/ so
|
|
46
|
+
// Ruby competence and fine-tune readiness can be computed per project.
|
|
47
|
+
/**
|
|
48
|
+
* Rough character-based token estimation (≈1 token per 4 characters).
|
|
49
|
+
* Used only for episode recording when the provider does not report usage
|
|
50
|
+
* (e.g. MiMo streaming, Google Gemini streaming).
|
|
51
|
+
*/
|
|
52
|
+
function estimateTokens(text) {
|
|
53
|
+
if (!text)
|
|
54
|
+
return 0;
|
|
55
|
+
return Math.ceil(text.length / 4);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* On-disk episode persistence for the Ruby Principle.
|
|
59
|
+
* Mirrors {@link sessionStore} — atomic `.tmp` writes, namespaced by project hash.
|
|
60
|
+
*/
|
|
61
|
+
exports.episodeStore = {
|
|
62
|
+
defaultDir() {
|
|
63
|
+
return path.join(process.env.HOME ?? '/tmp', '.aura', 'episodes');
|
|
64
|
+
},
|
|
65
|
+
/**
|
|
66
|
+
* First 8 characters of the base64 encoding of `projectRoot`.
|
|
67
|
+
*/
|
|
68
|
+
projectHash(projectRoot) {
|
|
69
|
+
return Buffer.from(projectRoot, 'utf8').toString('base64').slice(0, 8);
|
|
70
|
+
},
|
|
71
|
+
/** Directory containing all episodes for a project. */
|
|
72
|
+
projectDir(projectRoot) {
|
|
73
|
+
return path.join(this.defaultDir(), this.projectHash(projectRoot));
|
|
74
|
+
},
|
|
75
|
+
/** Full path to one episode file. */
|
|
76
|
+
episodePath(projectRoot, id) {
|
|
77
|
+
return path.join(this.projectDir(projectRoot), `${id}.json`);
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* Persists one episode to `~/.aura/episodes/{projectHash}/{id}.json`.
|
|
81
|
+
*
|
|
82
|
+
* When the provider did not report token usage (totalTokens === 0), fills in
|
|
83
|
+
* a character-based estimate from the episode's output text so that fine-tune
|
|
84
|
+
* readiness and competence tracking still have meaningful token counts.
|
|
85
|
+
*/
|
|
86
|
+
async saveEpisode(projectRoot, episode) {
|
|
87
|
+
// Fill estimated tokens when the provider reported 0
|
|
88
|
+
if (episode.rubyAttempted && !episode.tokensUsed.ruby) {
|
|
89
|
+
const est = estimateTokens(episode.rubyOutput);
|
|
90
|
+
if (est > 0)
|
|
91
|
+
episode = { ...episode, tokensUsed: { ...episode.tokensUsed, ruby: est } };
|
|
92
|
+
}
|
|
93
|
+
if (episode.largeModelUsed && !episode.tokensUsed.largeModel) {
|
|
94
|
+
const est = estimateTokens(episode.largeModelOutput);
|
|
95
|
+
if (est > 0)
|
|
96
|
+
episode = { ...episode, tokensUsed: { ...episode.tokensUsed, largeModel: est } };
|
|
97
|
+
}
|
|
98
|
+
const dir = this.projectDir(projectRoot);
|
|
99
|
+
if (!fs.existsSync(dir))
|
|
100
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
101
|
+
const filePath = this.episodePath(projectRoot, episode.id);
|
|
102
|
+
const tmp = filePath + '.tmp';
|
|
103
|
+
await fs.promises.writeFile(tmp, JSON.stringify(episode, null, 2), 'utf8');
|
|
104
|
+
await fs.promises.rename(tmp, filePath);
|
|
105
|
+
},
|
|
106
|
+
/**
|
|
107
|
+
* Loads episodes for a project, newest first.
|
|
108
|
+
* Never throws — returns `[]` on missing dir or parse errors.
|
|
109
|
+
*/
|
|
110
|
+
async loadEpisodes(projectRoot, limit) {
|
|
111
|
+
try {
|
|
112
|
+
const dir = this.projectDir(projectRoot);
|
|
113
|
+
if (!fs.existsSync(dir))
|
|
114
|
+
return [];
|
|
115
|
+
const files = fs.readdirSync(dir).filter(f => f.endsWith('.json'));
|
|
116
|
+
const episodes = [];
|
|
117
|
+
for (const file of files) {
|
|
118
|
+
const raw = await fs.promises.readFile(path.join(dir, file), 'utf8');
|
|
119
|
+
try {
|
|
120
|
+
const parsed = JSON.parse(raw);
|
|
121
|
+
if (parsed?.id && typeof parsed.timestamp === 'number') {
|
|
122
|
+
episodes.push(parsed);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
/* skip corrupt file */
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
episodes.sort((a, b) => b.timestamp - a.timestamp);
|
|
130
|
+
if (limit !== undefined && limit > 0) {
|
|
131
|
+
return episodes.slice(0, limit);
|
|
132
|
+
}
|
|
133
|
+
return episodes;
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return [];
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
/**
|
|
140
|
+
* Removes one episode file. Safe when the file does not exist.
|
|
141
|
+
*/
|
|
142
|
+
async deleteEpisode(projectRoot, id) {
|
|
143
|
+
const filePath = this.episodePath(projectRoot, id);
|
|
144
|
+
if (!fs.existsSync(filePath))
|
|
145
|
+
return;
|
|
146
|
+
await fs.promises.unlink(filePath);
|
|
147
|
+
},
|
|
148
|
+
/**
|
|
149
|
+
* Aggregates episode counters and fine-tune readiness for a project.
|
|
150
|
+
* Never throws — returns zeroed stats on error.
|
|
151
|
+
*/
|
|
152
|
+
async getEpisodeStats(projectRoot) {
|
|
153
|
+
try {
|
|
154
|
+
const episodes = await this.loadEpisodes(projectRoot);
|
|
155
|
+
let rubySuccesses = 0;
|
|
156
|
+
let rubyFailures = 0;
|
|
157
|
+
let largeModelInterventions = 0;
|
|
158
|
+
for (const ep of episodes) {
|
|
159
|
+
if (ep.rubyAttempted) {
|
|
160
|
+
if (ep.rubySucceeded)
|
|
161
|
+
rubySuccesses++;
|
|
162
|
+
else
|
|
163
|
+
rubyFailures++;
|
|
164
|
+
}
|
|
165
|
+
if (ep.largeModelUsed)
|
|
166
|
+
largeModelInterventions++;
|
|
167
|
+
}
|
|
168
|
+
return {
|
|
169
|
+
total: episodes.length,
|
|
170
|
+
rubySuccesses,
|
|
171
|
+
rubyFailures,
|
|
172
|
+
largeModelInterventions,
|
|
173
|
+
readyForFineTune: (0, competence_js_1.shouldFineTune)(episodes),
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return {
|
|
178
|
+
total: 0,
|
|
179
|
+
rubySuccesses: 0,
|
|
180
|
+
rubyFailures: 0,
|
|
181
|
+
largeModelInterventions: 0,
|
|
182
|
+
readyForFineTune: false,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
};
|
|
187
|
+
// Named re-exports (callers may import functions directly)
|
|
188
|
+
exports.saveEpisode = exports.episodeStore.saveEpisode.bind(exports.episodeStore);
|
|
189
|
+
exports.loadEpisodes = exports.episodeStore.loadEpisodes.bind(exports.episodeStore);
|
|
190
|
+
exports.deleteEpisode = exports.episodeStore.deleteEpisode.bind(exports.episodeStore);
|
|
191
|
+
exports.getEpisodeStats = exports.episodeStore.getEpisodeStats.bind(exports.episodeStore);
|
|
192
|
+
// estimateTokens is already a top-level export above
|
|
193
|
+
//# sourceMappingURL=episode-capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"episode-capture.js","sourceRoot":"","sources":["../../src/ruby/episode-capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { FineTuneJob } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a specialised Ollama model via `ollama create` and a generated Modelfile.
|
|
4
|
+
* Returns a completed or failed {@link FineTuneJob}; does not throw.
|
|
5
|
+
*/
|
|
6
|
+
export declare function fineTuneWithOllama(baseModel: string, trainingDataPath: string, outputModelName: string): Promise<FineTuneJob>;
|
|
7
|
+
/**
|
|
8
|
+
* Uploads JSONL training data and starts an OpenAI fine-tuning job.
|
|
9
|
+
* Returns `failed` when `OPENAI_API_KEY` is unset; does not throw.
|
|
10
|
+
*/
|
|
11
|
+
export declare function fineTuneWithOpenAI(trainingDataPath: string, baseModel?: string): Promise<FineTuneJob>;
|
|
12
|
+
/**
|
|
13
|
+
* Refreshes a {@link FineTuneJob} from Ollama tags or the OpenAI fine-tuning API.
|
|
14
|
+
* Never throws — returns the input job on unrecoverable errors.
|
|
15
|
+
*/
|
|
16
|
+
export declare function checkJobStatus(job: FineTuneJob): Promise<FineTuneJob>;
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.fineTuneWithOllama = fineTuneWithOllama;
|
|
40
|
+
exports.fineTuneWithOpenAI = fineTuneWithOpenAI;
|
|
41
|
+
exports.checkJobStatus = checkJobStatus;
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const os = __importStar(require("os"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const child_process_1 = require("child_process");
|
|
46
|
+
const util_1 = require("util");
|
|
47
|
+
const crypto_1 = require("crypto");
|
|
48
|
+
const openai_1 = __importDefault(require("openai"));
|
|
49
|
+
const env_js_1 = require("../util/env.js");
|
|
50
|
+
const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
|
|
51
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
52
|
+
// Ollama — Modelfile-based specialization (no native fine-tune API)
|
|
53
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
54
|
+
/**
|
|
55
|
+
* Creates a specialised Ollama model via `ollama create` and a generated Modelfile.
|
|
56
|
+
* Returns a completed or failed {@link FineTuneJob}; does not throw.
|
|
57
|
+
*/
|
|
58
|
+
async function fineTuneWithOllama(baseModel, trainingDataPath, outputModelName) {
|
|
59
|
+
const id = `ollama-${(0, crypto_1.randomUUID)()}`;
|
|
60
|
+
const startedAt = Date.now();
|
|
61
|
+
let trainingExamples = 0;
|
|
62
|
+
try {
|
|
63
|
+
const raw = await fs.promises.readFile(trainingDataPath, 'utf8');
|
|
64
|
+
const lines = raw.split('\n').filter(l => l.trim());
|
|
65
|
+
trainingExamples = lines.length;
|
|
66
|
+
const snippets = [];
|
|
67
|
+
for (const line of lines.slice(0, 50)) {
|
|
68
|
+
try {
|
|
69
|
+
const row = JSON.parse(line);
|
|
70
|
+
const user = row.messages?.find(m => m.role === 'user')?.content ?? '';
|
|
71
|
+
const assistant = row.messages?.find(m => m.role === 'assistant')?.content ?? '';
|
|
72
|
+
if (user || assistant) {
|
|
73
|
+
snippets.push(`User: ${user}\nAssistant: ${assistant}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
/* skip bad line */
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const systemBlock = [
|
|
81
|
+
'You are a specialized coding assistant.',
|
|
82
|
+
'Learn from these corrected examples where a larger model intervened:',
|
|
83
|
+
...snippets,
|
|
84
|
+
].join('\n\n');
|
|
85
|
+
const modelfile = [
|
|
86
|
+
`FROM ${baseModel}`,
|
|
87
|
+
'SYSTEM """',
|
|
88
|
+
systemBlock.replace(/"""/g, "'''"),
|
|
89
|
+
'"""',
|
|
90
|
+
].join('\n');
|
|
91
|
+
const tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'rubycode-ft-'));
|
|
92
|
+
const modelfilePath = path.join(tmpDir, 'Modelfile');
|
|
93
|
+
await fs.promises.writeFile(modelfilePath, modelfile, 'utf8');
|
|
94
|
+
await execFileAsync('ollama', ['create', outputModelName, '-f', modelfilePath], {
|
|
95
|
+
timeout: 300_000,
|
|
96
|
+
});
|
|
97
|
+
return {
|
|
98
|
+
id,
|
|
99
|
+
status: 'completed',
|
|
100
|
+
baseModel,
|
|
101
|
+
trainingExamples,
|
|
102
|
+
outputModel: outputModelName,
|
|
103
|
+
startedAt,
|
|
104
|
+
completedAt: Date.now(),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
return {
|
|
109
|
+
id,
|
|
110
|
+
status: 'failed',
|
|
111
|
+
baseModel,
|
|
112
|
+
trainingExamples,
|
|
113
|
+
outputModel: outputModelName,
|
|
114
|
+
startedAt,
|
|
115
|
+
completedAt: Date.now(),
|
|
116
|
+
error: String(e),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
121
|
+
// OpenAI — native fine-tuning API
|
|
122
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
123
|
+
/**
|
|
124
|
+
* Uploads JSONL training data and starts an OpenAI fine-tuning job.
|
|
125
|
+
* Returns `failed` when `OPENAI_API_KEY` is unset; does not throw.
|
|
126
|
+
*/
|
|
127
|
+
async function fineTuneWithOpenAI(trainingDataPath, baseModel = 'gpt-3.5-turbo') {
|
|
128
|
+
const startedAt = Date.now();
|
|
129
|
+
const apiKey = (0, env_js_1.getApiKey)('OPENAI_API_KEY');
|
|
130
|
+
if (!apiKey) {
|
|
131
|
+
return {
|
|
132
|
+
id: `openai-${(0, crypto_1.randomUUID)()}`,
|
|
133
|
+
status: 'failed',
|
|
134
|
+
baseModel,
|
|
135
|
+
trainingExamples: 0,
|
|
136
|
+
outputModel: '',
|
|
137
|
+
startedAt,
|
|
138
|
+
completedAt: Date.now(),
|
|
139
|
+
error: 'OPENAI_API_KEY is not set',
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
try {
|
|
143
|
+
const raw = await fs.promises.readFile(trainingDataPath, 'utf8');
|
|
144
|
+
const trainingExamples = raw.split('\n').filter(l => l.trim()).length;
|
|
145
|
+
const client = new openai_1.default({ apiKey });
|
|
146
|
+
const file = await client.files.create({
|
|
147
|
+
file: fs.createReadStream(trainingDataPath),
|
|
148
|
+
purpose: 'fine-tune',
|
|
149
|
+
});
|
|
150
|
+
const job = await client.fineTuning.jobs.create({
|
|
151
|
+
training_file: file.id,
|
|
152
|
+
model: baseModel,
|
|
153
|
+
});
|
|
154
|
+
return {
|
|
155
|
+
id: `openai-${job.id}`,
|
|
156
|
+
status: 'running',
|
|
157
|
+
baseModel,
|
|
158
|
+
trainingExamples,
|
|
159
|
+
outputModel: job.fine_tuned_model ?? '',
|
|
160
|
+
startedAt,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
catch (e) {
|
|
164
|
+
return {
|
|
165
|
+
id: `openai-${(0, crypto_1.randomUUID)()}`,
|
|
166
|
+
status: 'failed',
|
|
167
|
+
baseModel,
|
|
168
|
+
trainingExamples: 0,
|
|
169
|
+
outputModel: '',
|
|
170
|
+
startedAt,
|
|
171
|
+
completedAt: Date.now(),
|
|
172
|
+
error: String(e),
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
177
|
+
// Job status
|
|
178
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
179
|
+
/**
|
|
180
|
+
* Refreshes a {@link FineTuneJob} from Ollama tags or the OpenAI fine-tuning API.
|
|
181
|
+
* Never throws — returns the input job on unrecoverable errors.
|
|
182
|
+
*/
|
|
183
|
+
async function checkJobStatus(job) {
|
|
184
|
+
try {
|
|
185
|
+
if (!job?.id)
|
|
186
|
+
return job;
|
|
187
|
+
if (job.id.startsWith('openai-')) {
|
|
188
|
+
return checkOpenAIJobStatus(job);
|
|
189
|
+
}
|
|
190
|
+
return checkOllamaJobStatus(job);
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
return job;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
async function checkOllamaJobStatus(job) {
|
|
197
|
+
if (job.status === 'failed' || job.status === 'completed')
|
|
198
|
+
return job;
|
|
199
|
+
try {
|
|
200
|
+
const res = await fetch('http://localhost:11434/api/tags');
|
|
201
|
+
if (!res.ok)
|
|
202
|
+
return { ...job, status: 'failed', error: 'Ollama tags API unreachable' };
|
|
203
|
+
const body = (await res.json());
|
|
204
|
+
const names = (body.models ?? []).map(m => m.name);
|
|
205
|
+
const exists = names.some(n => n === job.outputModel ||
|
|
206
|
+
n.startsWith(`${job.outputModel}:`) ||
|
|
207
|
+
n.split(':')[0] === job.outputModel);
|
|
208
|
+
if (exists) {
|
|
209
|
+
return { ...job, status: 'completed', completedAt: job.completedAt ?? Date.now() };
|
|
210
|
+
}
|
|
211
|
+
return { ...job, status: 'failed', error: `Model ${job.outputModel} not found in Ollama` };
|
|
212
|
+
}
|
|
213
|
+
catch (e) {
|
|
214
|
+
return { ...job, status: 'failed', error: String(e), completedAt: Date.now() };
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
async function checkOpenAIJobStatus(job) {
|
|
218
|
+
const apiKey = (0, env_js_1.getApiKey)('OPENAI_API_KEY');
|
|
219
|
+
if (!apiKey) {
|
|
220
|
+
return {
|
|
221
|
+
...job,
|
|
222
|
+
status: 'failed',
|
|
223
|
+
error: 'OPENAI_API_KEY is not set',
|
|
224
|
+
completedAt: Date.now(),
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
const openaiId = job.id.replace(/^openai-/, '');
|
|
228
|
+
try {
|
|
229
|
+
const client = new openai_1.default({ apiKey });
|
|
230
|
+
const remote = await client.fineTuning.jobs.retrieve(openaiId);
|
|
231
|
+
const statusMap = {
|
|
232
|
+
validating_files: 'pending',
|
|
233
|
+
queued: 'pending',
|
|
234
|
+
running: 'running',
|
|
235
|
+
succeeded: 'completed',
|
|
236
|
+
failed: 'failed',
|
|
237
|
+
cancelled: 'failed',
|
|
238
|
+
};
|
|
239
|
+
const status = statusMap[remote.status] ?? job.status;
|
|
240
|
+
const terminal = status === 'completed' || status === 'failed';
|
|
241
|
+
return {
|
|
242
|
+
...job,
|
|
243
|
+
status,
|
|
244
|
+
outputModel: remote.fine_tuned_model ?? job.outputModel,
|
|
245
|
+
completedAt: terminal ? Date.now() : job.completedAt,
|
|
246
|
+
error: remote.error?.message ?? job.error,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
return { ...job, status: 'failed', error: String(e), completedAt: Date.now() };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=fine-tune.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fine-tune.js","sourceRoot":"","sources":["../../src/ruby/fine-tune.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { RubyModel } from './ruby-model.js';
|
|
2
|
+
export { RubyAlternator } from './alternator.js';
|
|
3
|
+
export type { AlternatorOptions, AlternatorRunResult } from './alternator.js';
|
|
4
|
+
export { assessCompetence, updateCompetence, getCompetenceReport, shouldFineTune, } from './competence.js';
|
|
5
|
+
export { saveEpisode, loadEpisodes, getEpisodeStats, } from './episode-capture.js';
|
|
6
|
+
export type { EpisodeStats } from './episode-capture.js';
|
|
7
|
+
export { generateTrainingData, exportJSONL, } from './training-data.js';
|
|
8
|
+
export { fineTuneWithOllama, fineTuneWithOpenAI, checkJobStatus, } from './fine-tune.js';
|
|
9
|
+
export type { Episode, RubyConfig, CompetenceLevel, AlternationDecision, TrainingExample, FineTuneJob, TaskCategory, } from './types.js';
|
|
10
|
+
export { DEFAULT_RUBY_CONFIG } from './types.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_RUBY_CONFIG = exports.checkJobStatus = exports.fineTuneWithOpenAI = exports.fineTuneWithOllama = exports.exportJSONL = exports.generateTrainingData = exports.getEpisodeStats = exports.loadEpisodes = exports.saveEpisode = exports.shouldFineTune = exports.getCompetenceReport = exports.updateCompetence = exports.assessCompetence = exports.RubyAlternator = exports.RubyModel = void 0;
|
|
4
|
+
var ruby_model_js_1 = require("./ruby-model.js");
|
|
5
|
+
Object.defineProperty(exports, "RubyModel", { enumerable: true, get: function () { return ruby_model_js_1.RubyModel; } });
|
|
6
|
+
var alternator_js_1 = require("./alternator.js");
|
|
7
|
+
Object.defineProperty(exports, "RubyAlternator", { enumerable: true, get: function () { return alternator_js_1.RubyAlternator; } });
|
|
8
|
+
var competence_js_1 = require("./competence.js");
|
|
9
|
+
Object.defineProperty(exports, "assessCompetence", { enumerable: true, get: function () { return competence_js_1.assessCompetence; } });
|
|
10
|
+
Object.defineProperty(exports, "updateCompetence", { enumerable: true, get: function () { return competence_js_1.updateCompetence; } });
|
|
11
|
+
Object.defineProperty(exports, "getCompetenceReport", { enumerable: true, get: function () { return competence_js_1.getCompetenceReport; } });
|
|
12
|
+
Object.defineProperty(exports, "shouldFineTune", { enumerable: true, get: function () { return competence_js_1.shouldFineTune; } });
|
|
13
|
+
var episode_capture_js_1 = require("./episode-capture.js");
|
|
14
|
+
Object.defineProperty(exports, "saveEpisode", { enumerable: true, get: function () { return episode_capture_js_1.saveEpisode; } });
|
|
15
|
+
Object.defineProperty(exports, "loadEpisodes", { enumerable: true, get: function () { return episode_capture_js_1.loadEpisodes; } });
|
|
16
|
+
Object.defineProperty(exports, "getEpisodeStats", { enumerable: true, get: function () { return episode_capture_js_1.getEpisodeStats; } });
|
|
17
|
+
var training_data_js_1 = require("./training-data.js");
|
|
18
|
+
Object.defineProperty(exports, "generateTrainingData", { enumerable: true, get: function () { return training_data_js_1.generateTrainingData; } });
|
|
19
|
+
Object.defineProperty(exports, "exportJSONL", { enumerable: true, get: function () { return training_data_js_1.exportJSONL; } });
|
|
20
|
+
var fine_tune_js_1 = require("./fine-tune.js");
|
|
21
|
+
Object.defineProperty(exports, "fineTuneWithOllama", { enumerable: true, get: function () { return fine_tune_js_1.fineTuneWithOllama; } });
|
|
22
|
+
Object.defineProperty(exports, "fineTuneWithOpenAI", { enumerable: true, get: function () { return fine_tune_js_1.fineTuneWithOpenAI; } });
|
|
23
|
+
Object.defineProperty(exports, "checkJobStatus", { enumerable: true, get: function () { return fine_tune_js_1.checkJobStatus; } });
|
|
24
|
+
var types_js_1 = require("./types.js");
|
|
25
|
+
Object.defineProperty(exports, "DEFAULT_RUBY_CONFIG", { enumerable: true, get: function () { return types_js_1.DEFAULT_RUBY_CONFIG; } });
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ruby/index.ts"],"names":[],"mappings":";;;AAAA,iDAA4C;AAAnC,0GAAA,SAAS,OAAA;AAClB,iDAAiD;AAAxC,+GAAA,cAAc,OAAA;AAEvB,iDAKyB;AAJvB,iHAAA,gBAAgB,OAAA;AAChB,iHAAA,gBAAgB,OAAA;AAChB,oHAAA,mBAAmB,OAAA;AACnB,+GAAA,cAAc,OAAA;AAEhB,2DAI8B;AAH5B,iHAAA,WAAW,OAAA;AACX,kHAAA,YAAY,OAAA;AACZ,qHAAA,eAAe,OAAA;AAGjB,uDAG4B;AAF1B,wHAAA,oBAAoB,OAAA;AACpB,+GAAA,WAAW,OAAA;AAEb,+CAIwB;AAHtB,kHAAA,kBAAkB,OAAA;AAClB,kHAAA,kBAAkB,OAAA;AAClB,8GAAA,cAAc,OAAA;AAWhB,uCAAiD;AAAxC,+GAAA,mBAAmB,OAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { LLMProvider, ToolDefinition, HistoryMessage, LLMResponse, StreamChunk } from '../providers/types.js';
|
|
2
|
+
import type { RubyConfig } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* {@link LLMProvider} implementation for the Ruby Principle small model.
|
|
5
|
+
* Delegates completions to {@link OpenAICompatibleProvider} against Ollama.
|
|
6
|
+
*/
|
|
7
|
+
export declare class RubyModel implements LLMProvider {
|
|
8
|
+
readonly name = "Ruby";
|
|
9
|
+
supportsTools: boolean;
|
|
10
|
+
model: string;
|
|
11
|
+
private readonly config;
|
|
12
|
+
private delegate;
|
|
13
|
+
constructor(config: RubyConfig);
|
|
14
|
+
/**
|
|
15
|
+
* One-shot completion via the Ollama OpenAI-compatible endpoint.
|
|
16
|
+
*/
|
|
17
|
+
complete(system: string, history: HistoryMessage[], tools: ToolDefinition[]): Promise<LLMResponse>;
|
|
18
|
+
/**
|
|
19
|
+
* Streaming completion via the Ollama OpenAI-compatible endpoint.
|
|
20
|
+
*/
|
|
21
|
+
stream(system: string, history: HistoryMessage[], tools: ToolDefinition[]): AsyncGenerator<StreamChunk>;
|
|
22
|
+
/**
|
|
23
|
+
* Returns true when Ollama is reachable and lists {@link model}.
|
|
24
|
+
* Never throws.
|
|
25
|
+
*/
|
|
26
|
+
isAvailable(): Promise<boolean>;
|
|
27
|
+
/**
|
|
28
|
+
* Returns the current Ollama model tag in use.
|
|
29
|
+
*/
|
|
30
|
+
getVersion(): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Switches the active Ollama model and rebuilds the delegate provider.
|
|
33
|
+
*/
|
|
34
|
+
updateModel(newModelName: string): Promise<void>;
|
|
35
|
+
private buildDelegate;
|
|
36
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RubyModel = void 0;
|
|
4
|
+
const openai_compatible_js_1 = require("../providers/openai-compatible.js");
|
|
5
|
+
/**
|
|
6
|
+
* {@link LLMProvider} implementation for the Ruby Principle small model.
|
|
7
|
+
* Delegates completions to {@link OpenAICompatibleProvider} against Ollama.
|
|
8
|
+
*/
|
|
9
|
+
class RubyModel {
|
|
10
|
+
name = 'Ruby';
|
|
11
|
+
supportsTools = true;
|
|
12
|
+
model;
|
|
13
|
+
config;
|
|
14
|
+
delegate;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
this.model = config.modelName;
|
|
18
|
+
this.delegate = this.buildDelegate();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* One-shot completion via the Ollama OpenAI-compatible endpoint.
|
|
22
|
+
*/
|
|
23
|
+
async complete(system, history, tools) {
|
|
24
|
+
return this.delegate.complete(system, history, tools);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Streaming completion via the Ollama OpenAI-compatible endpoint.
|
|
28
|
+
*/
|
|
29
|
+
async *stream(system, history, tools) {
|
|
30
|
+
yield* this.delegate.stream(system, history, tools);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Returns true when Ollama is reachable and lists {@link model}.
|
|
34
|
+
* Never throws.
|
|
35
|
+
*/
|
|
36
|
+
async isAvailable() {
|
|
37
|
+
try {
|
|
38
|
+
const root = ollamaRoot(this.config.ollamaBaseUrl);
|
|
39
|
+
const controller = new AbortController();
|
|
40
|
+
const timer = setTimeout(() => controller.abort(), 3_000);
|
|
41
|
+
const res = await fetch(`${root}/api/tags`, { signal: controller.signal });
|
|
42
|
+
clearTimeout(timer);
|
|
43
|
+
if (!res.ok)
|
|
44
|
+
return false;
|
|
45
|
+
const body = (await res.json());
|
|
46
|
+
const names = (body.models ?? []).map(m => m.name);
|
|
47
|
+
const wanted = this.model;
|
|
48
|
+
return names.some(n => n === wanted || n.startsWith(`${wanted}:`) || n.split(':')[0] === wanted);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Returns the current Ollama model tag in use.
|
|
56
|
+
*/
|
|
57
|
+
async getVersion() {
|
|
58
|
+
return this.model;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Switches the active Ollama model and rebuilds the delegate provider.
|
|
62
|
+
*/
|
|
63
|
+
async updateModel(newModelName) {
|
|
64
|
+
this.model = newModelName;
|
|
65
|
+
this.config.modelName = newModelName;
|
|
66
|
+
this.delegate = this.buildDelegate();
|
|
67
|
+
}
|
|
68
|
+
buildDelegate() {
|
|
69
|
+
return new openai_compatible_js_1.OpenAICompatibleProvider({
|
|
70
|
+
model: this.model,
|
|
71
|
+
baseUrl: this.config.ollamaBaseUrl,
|
|
72
|
+
apiKey: 'ollama',
|
|
73
|
+
}, 'Ruby');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
exports.RubyModel = RubyModel;
|
|
77
|
+
function ollamaRoot(baseUrl) {
|
|
78
|
+
const trimmed = (baseUrl ?? 'http://localhost:11434/v1').replace(/\/v1\/?$/, '').replace(/\/$/, '');
|
|
79
|
+
return trimmed || 'http://localhost:11434';
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=ruby-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ruby-model.js","sourceRoot":"","sources":["../../src/ruby/ruby-model.ts"],"names":[],"mappings":"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"}
|