augure 0.4.0 → 0.4.2

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.
Files changed (2) hide show
  1. package/dist/bin.js +244 -18
  2. package/package.json +20 -20
package/dist/bin.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/bin.ts
4
- import { createRequire } from "module";
4
+ import { createRequire as createRequire2 } from "module";
5
5
  import { defineCommand as defineCommand4, runMain } from "citty";
6
6
 
7
7
  // src/commands/start.ts
@@ -198,11 +198,15 @@ var OpenRouterClient = class {
198
198
  const choice = data.choices[0];
199
199
  return {
200
200
  content: choice.message.content ?? "",
201
- toolCalls: (choice.message.tool_calls ?? []).map((tc) => ({
202
- id: tc.id,
203
- name: tc.function.name,
204
- arguments: JSON.parse(tc.function.arguments)
205
- })),
201
+ toolCalls: (choice.message.tool_calls ?? []).map((tc) => {
202
+ let args = {};
203
+ try {
204
+ args = tc.function.arguments ? JSON.parse(tc.function.arguments) : {};
205
+ } catch {
206
+ console.error(`[augure] Failed to parse tool call arguments for ${tc.function.name}:`, tc.function.arguments);
207
+ }
208
+ return { id: tc.id, name: tc.function.name, arguments: args };
209
+ }),
206
210
  usage: {
207
211
  inputTokens: data.usage.prompt_tokens,
208
212
  outputTokens: data.usage.completion_tokens
@@ -712,7 +716,8 @@ function createSplitMessageMiddleware(sendFn, maxLength = TELEGRAM_MAX) {
712
716
  // ../channels/dist/middleware/error-handler.js
713
717
  function isRetryable(error) {
714
718
  if (error instanceof Error) {
715
- const status = error.status;
719
+ const err2 = error;
720
+ const status = err2.status ?? err2.error_code;
716
721
  if (status === 429 || status !== void 0 && status >= 500)
717
722
  return true;
718
723
  if (status !== void 0 && status >= 400 && status < 500)
@@ -3163,8 +3168,150 @@ async function installBuiltins(manager) {
3163
3168
  }
3164
3169
  }
3165
3170
 
3171
+ // ../skills/dist/updater.js
3172
+ var SkillUpdater = class {
3173
+ config;
3174
+ constructor(config) {
3175
+ this.config = config;
3176
+ }
3177
+ /** Compare local skill versions with hub manifest */
3178
+ async checkForUpdates() {
3179
+ const [local, remote] = await Promise.all([
3180
+ this.config.manager.list(),
3181
+ this.config.hub.list()
3182
+ ]);
3183
+ const localMap = new Map(local.map((s) => [s.id, s.version]));
3184
+ const updates = [];
3185
+ for (const entry of remote) {
3186
+ const localVersion = localMap.get(entry.id);
3187
+ if (localVersion !== void 0 && entry.version > localVersion) {
3188
+ updates.push({
3189
+ id: entry.id,
3190
+ localVersion,
3191
+ hubVersion: entry.version
3192
+ });
3193
+ }
3194
+ }
3195
+ return updates;
3196
+ }
3197
+ /** Apply a single skill update with backup and rollback */
3198
+ async applyUpdate(skillId) {
3199
+ let backup;
3200
+ try {
3201
+ backup = await this.config.manager.get(skillId);
3202
+ } catch (err2) {
3203
+ return {
3204
+ skillId,
3205
+ success: false,
3206
+ fromVersion: 0,
3207
+ toVersion: 0,
3208
+ error: `Failed to backup: ${err2 instanceof Error ? err2.message : String(err2)}`
3209
+ };
3210
+ }
3211
+ const fromVersion = backup.meta.version;
3212
+ let newSkill;
3213
+ try {
3214
+ newSkill = await this.config.hub.download(skillId);
3215
+ } catch (err2) {
3216
+ return {
3217
+ skillId,
3218
+ success: false,
3219
+ fromVersion,
3220
+ toVersion: 0,
3221
+ error: `Failed to download: ${err2 instanceof Error ? err2.message : String(err2)}`
3222
+ };
3223
+ }
3224
+ const toVersion = newSkill.meta.version;
3225
+ const testResult = await this.config.tester.test(newSkill);
3226
+ if (testResult.success) {
3227
+ await this.config.manager.save(newSkill);
3228
+ return { skillId, success: true, fromVersion, toVersion };
3229
+ }
3230
+ await this.config.manager.save(backup);
3231
+ return {
3232
+ skillId,
3233
+ success: false,
3234
+ rolledBack: true,
3235
+ fromVersion,
3236
+ toVersion,
3237
+ error: `Update failed tests: ${testResult.error ?? "unknown"}`
3238
+ };
3239
+ }
3240
+ /** Check for updates and apply all available ones */
3241
+ async checkAndApply() {
3242
+ const updates = await this.checkForUpdates();
3243
+ const results = [];
3244
+ for (const update of updates) {
3245
+ try {
3246
+ const result = await this.applyUpdate(update.id);
3247
+ results.push(result);
3248
+ } catch (err2) {
3249
+ results.push({
3250
+ skillId: update.id,
3251
+ success: false,
3252
+ fromVersion: update.localVersion,
3253
+ toVersion: update.hubVersion,
3254
+ error: err2 instanceof Error ? err2.message : String(err2)
3255
+ });
3256
+ }
3257
+ }
3258
+ return results;
3259
+ }
3260
+ };
3261
+
3166
3262
  // ../core/dist/main.js
3167
3263
  import { resolve } from "path";
3264
+ import { createRequire } from "module";
3265
+
3266
+ // ../core/dist/version-checker.js
3267
+ var VersionChecker = class _VersionChecker {
3268
+ config;
3269
+ constructor(config) {
3270
+ this.config = config;
3271
+ }
3272
+ /** Check npm registry for latest version */
3273
+ async check() {
3274
+ try {
3275
+ const response = await fetch(`https://registry.npmjs.org/${this.config.packageName}/latest`);
3276
+ if (!response.ok) {
3277
+ return {
3278
+ updateAvailable: false,
3279
+ currentVersion: this.config.currentVersion,
3280
+ error: `npm registry returned ${response.status}`
3281
+ };
3282
+ }
3283
+ const data = await response.json();
3284
+ const latest = data.version;
3285
+ return {
3286
+ updateAvailable: _VersionChecker.compareVersions(this.config.currentVersion, latest) < 0,
3287
+ currentVersion: this.config.currentVersion,
3288
+ latestVersion: latest
3289
+ };
3290
+ } catch (err2) {
3291
+ return {
3292
+ updateAvailable: false,
3293
+ currentVersion: this.config.currentVersion,
3294
+ error: err2 instanceof Error ? err2.message : String(err2)
3295
+ };
3296
+ }
3297
+ }
3298
+ /** Compare two semver strings. Returns -1 if a < b, 0 if equal, 1 if a > b */
3299
+ static compareVersions(a, b) {
3300
+ const pa = a.split(".").map(Number);
3301
+ const pb = b.split(".").map(Number);
3302
+ for (let i = 0; i < 3; i++) {
3303
+ const va = pa[i] ?? 0;
3304
+ const vb = pb[i] ?? 0;
3305
+ if (va < vb)
3306
+ return -1;
3307
+ if (va > vb)
3308
+ return 1;
3309
+ }
3310
+ return 0;
3311
+ }
3312
+ };
3313
+
3314
+ // ../core/dist/main.js
3168
3315
  var SYSTEM_PROMPT = `You are Augure, a personal AI assistant. You are proactive, helpful, and concise.
3169
3316
  You speak the same language as the user. You have access to tools and persistent memory.
3170
3317
  Always be direct and actionable.`;
@@ -3179,7 +3326,7 @@ function resolveLLMClient(config, usage) {
3179
3326
  async function startAgent(configPath) {
3180
3327
  const config = await loadConfig(configPath);
3181
3328
  console.log(`[augure] Loaded config: ${config.identity.name}`);
3182
- let telegramChannel;
3329
+ let telegram;
3183
3330
  const llm = resolveLLMClient(config.llm, "default");
3184
3331
  const ingestionLLM = resolveLLMClient(config.llm, "ingestion");
3185
3332
  const monitoringLLM = resolveLLMClient(config.llm, "monitoring");
@@ -3215,6 +3362,7 @@ async function startAgent(configPath) {
3215
3362
  });
3216
3363
  console.log(`[augure] Container pool created (max: ${config.security.maxConcurrentSandboxes})`);
3217
3364
  let skillManagerRef;
3365
+ let skillUpdater;
3218
3366
  if (config.skills) {
3219
3367
  const skillsPath = resolve(configPath, "..", config.skills.path);
3220
3368
  const codingLLM = resolveLLMClient(config.llm, "coding");
@@ -3250,6 +3398,26 @@ async function startAgent(configPath) {
3250
3398
  }
3251
3399
  const skillBridge = new SkillSchedulerBridge(scheduler, skillManager);
3252
3400
  await skillBridge.syncAll();
3401
+ if (hub && config.updates?.skills?.enabled !== false) {
3402
+ skillUpdater = new SkillUpdater({
3403
+ manager: skillManager,
3404
+ hub,
3405
+ tester: skillTester
3406
+ });
3407
+ try {
3408
+ const updateResults = await skillUpdater.checkAndApply();
3409
+ const updated = updateResults.filter((r) => r.success);
3410
+ const failed = updateResults.filter((r) => !r.success);
3411
+ if (updated.length > 0) {
3412
+ console.log(`[augure] Skills updated: ${updated.map((r) => `${r.skillId} (v${r.fromVersion}\u2192v${r.toVersion})`).join(", ")}`);
3413
+ }
3414
+ if (failed.length > 0) {
3415
+ console.log(`[augure] Skill updates failed: ${failed.map((r) => `${r.skillId}: ${r.error}`).join(", ")}`);
3416
+ }
3417
+ } catch (err2) {
3418
+ console.error("[augure] Skill update check failed:", err2);
3419
+ }
3420
+ }
3253
3421
  skillManagerRef = skillManager;
3254
3422
  console.log(`[augure] Skills system initialized at ${skillsPath}`);
3255
3423
  }
@@ -3265,6 +3433,19 @@ async function startAgent(configPath) {
3265
3433
  await personaResolver.loadAll();
3266
3434
  console.log(`[augure] Personas loaded from ${personaPath}`);
3267
3435
  }
3436
+ if (config.updates?.cli?.enabled !== false) {
3437
+ const require3 = createRequire(import.meta.url);
3438
+ const { version: version2 } = require3("augure/package.json");
3439
+ const versionChecker = new VersionChecker({
3440
+ currentVersion: version2,
3441
+ packageName: "augure",
3442
+ githubRepo: "FaureAlexis/augure"
3443
+ });
3444
+ const versionResult = await versionChecker.check();
3445
+ if (versionResult.updateAvailable) {
3446
+ console.log(`[augure] Update available: v${versionResult.latestVersion} (current: v${versionResult.currentVersion}). Run: npm update -g augure`);
3447
+ }
3448
+ }
3268
3449
  const guard = new ContextGuard({
3269
3450
  maxContextTokens: 2e5,
3270
3451
  reservedForOutput: config.llm.default.maxTokens ?? 8192
@@ -3281,23 +3462,24 @@ async function startAgent(configPath) {
3281
3462
  modelName: config.llm.default.model
3282
3463
  });
3283
3464
  if (config.channels.telegram?.enabled) {
3284
- const telegram = new TelegramChannel({
3465
+ telegram = new TelegramChannel({
3285
3466
  botToken: config.channels.telegram.botToken,
3286
3467
  allowedUsers: config.channels.telegram.allowedUsers,
3287
3468
  rejectMessage: config.channels.telegram.rejectMessage
3288
3469
  });
3470
+ const tg = telegram;
3289
3471
  const commandCtx = {
3290
3472
  scheduler,
3291
3473
  pool,
3292
3474
  agent,
3293
3475
  skillManager: skillManagerRef
3294
3476
  };
3295
- telegram.onMessage(async (msg) => {
3477
+ tg.onMessage(async (msg) => {
3296
3478
  console.log(`[augure] Message from ${msg.userId}: ${msg.text}`);
3297
3479
  try {
3298
3480
  const cmdResult = await handleCommand(msg.text, commandCtx);
3299
3481
  if (cmdResult.handled) {
3300
- await telegram.send({
3482
+ await tg.send({
3301
3483
  channelType: "telegram",
3302
3484
  userId: msg.userId,
3303
3485
  text: cmdResult.response ?? "OK",
@@ -3309,7 +3491,7 @@ async function startAgent(configPath) {
3309
3491
  agent.setPersona(personaResolver.resolve(msg.text));
3310
3492
  }
3311
3493
  const response = await agent.handleMessage(msg);
3312
- await telegram.send({
3494
+ await tg.send({
3313
3495
  channelType: "telegram",
3314
3496
  userId: msg.userId,
3315
3497
  text: response,
@@ -3317,15 +3499,14 @@ async function startAgent(configPath) {
3317
3499
  });
3318
3500
  } catch (err2) {
3319
3501
  console.error("[augure] Error handling message:", err2);
3320
- await telegram.send({
3502
+ await tg.send({
3321
3503
  channelType: "telegram",
3322
3504
  userId: msg.userId,
3323
3505
  text: "An error occurred while processing your message."
3324
3506
  });
3325
3507
  }
3326
3508
  });
3327
- await telegram.start();
3328
- telegramChannel = telegram;
3509
+ await tg.start();
3329
3510
  console.log("[augure] Telegram bot started. Waiting for messages...");
3330
3511
  }
3331
3512
  const heartbeatIntervalMs = parseInterval(config.scheduler.heartbeatInterval);
@@ -3348,12 +3529,57 @@ async function startAgent(configPath) {
3348
3529
  scheduler.start();
3349
3530
  heartbeat.start();
3350
3531
  console.log(`[augure] Scheduler started with ${scheduler.listJobs().length} jobs. Heartbeat every ${config.scheduler.heartbeatInterval}.`);
3532
+ if (skillUpdater && config.updates?.skills?.checkInterval) {
3533
+ const skillCheckMs = parseInterval(config.updates.skills.checkInterval);
3534
+ setInterval(async () => {
3535
+ try {
3536
+ const results = await skillUpdater.checkAndApply();
3537
+ for (const r of results) {
3538
+ if (r.success) {
3539
+ console.log(`[augure] Skill auto-updated: ${r.skillId} v${r.fromVersion}\u2192v${r.toVersion}`);
3540
+ } else if (r.rolledBack) {
3541
+ console.log(`[augure] Skill update rolled back: ${r.skillId} - ${r.error}`);
3542
+ }
3543
+ }
3544
+ } catch (err2) {
3545
+ console.error("[augure] Periodic skill update check failed:", err2);
3546
+ }
3547
+ }, skillCheckMs);
3548
+ }
3549
+ if (config.updates?.cli?.enabled !== false && config.channels.telegram?.enabled) {
3550
+ const cliCheckMs = parseInterval(config.updates?.cli?.checkInterval ?? "24h");
3551
+ const require3 = createRequire(import.meta.url);
3552
+ const { version: version2 } = require3("augure/package.json");
3553
+ const versionChecker = new VersionChecker({
3554
+ currentVersion: version2,
3555
+ packageName: "augure",
3556
+ githubRepo: "FaureAlexis/augure"
3557
+ });
3558
+ setInterval(async () => {
3559
+ try {
3560
+ const result = await versionChecker.check();
3561
+ if (result.updateAvailable && telegram) {
3562
+ const userId = config.channels.telegram?.allowedUsers[0];
3563
+ if (userId !== void 0) {
3564
+ await telegram.send({
3565
+ channelType: "telegram",
3566
+ userId: String(userId),
3567
+ text: `Update available: Augure v${result.latestVersion} (current: v${result.currentVersion}).
3568
+ Run: \`npm update -g augure\``
3569
+ });
3570
+ }
3571
+ }
3572
+ } catch (err2) {
3573
+ console.error("[augure] CLI version check failed:", err2);
3574
+ }
3575
+ }, cliCheckMs);
3576
+ }
3351
3577
  const shutdown = async () => {
3352
3578
  console.log("\n[augure] Shutting down...");
3353
3579
  heartbeat.stop();
3354
3580
  scheduler.stop();
3355
- if (telegramChannel)
3356
- await telegramChannel.stop();
3581
+ if (telegram)
3582
+ await telegram.stop();
3357
3583
  await pool.destroyAll();
3358
3584
  await audit.close();
3359
3585
  console.log("[augure] All containers destroyed");
@@ -3751,7 +3977,7 @@ var skillsCommand = defineCommand3({
3751
3977
  });
3752
3978
 
3753
3979
  // src/bin.ts
3754
- var require2 = createRequire(import.meta.url);
3980
+ var require2 = createRequire2(import.meta.url);
3755
3981
  var { version } = require2("../package.json");
3756
3982
  var main = defineCommand4({
3757
3983
  meta: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "augure",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Augure — your proactive AI agent",
5
5
  "type": "module",
6
6
  "bin": {
@@ -12,6 +12,15 @@
12
12
  "engines": {
13
13
  "node": ">=22.0.0"
14
14
  },
15
+ "scripts": {
16
+ "build": "tsup",
17
+ "dev": "tsup --watch",
18
+ "test": "vitest run",
19
+ "test:unit": "vitest run",
20
+ "typecheck": "tsc --noEmit",
21
+ "lint": "eslint src/",
22
+ "clean": "rm -rf dist .turbo"
23
+ },
15
24
  "dependencies": {
16
25
  "citty": "^0.2.1",
17
26
  "dockerode": "^4.0.9",
@@ -24,17 +33,17 @@
24
33
  "zod": "^4.3.6"
25
34
  },
26
35
  "devDependencies": {
36
+ "@augure/channels": "workspace:*",
37
+ "@augure/core": "workspace:*",
38
+ "@augure/memory": "workspace:*",
39
+ "@augure/sandbox": "workspace:*",
40
+ "@augure/scheduler": "workspace:*",
41
+ "@augure/skills": "workspace:*",
42
+ "@augure/tools": "workspace:*",
43
+ "@augure/types": "workspace:*",
27
44
  "@types/dockerode": "^4.0.1",
28
45
  "@types/node-cron": "^3.0.11",
29
- "tsup": "^8.5.1",
30
- "@augure/core": "0.1.0",
31
- "@augure/memory": "0.0.2",
32
- "@augure/sandbox": "0.0.2",
33
- "@augure/channels": "0.1.0",
34
- "@augure/scheduler": "0.0.2",
35
- "@augure/tools": "0.0.2",
36
- "@augure/types": "0.1.0",
37
- "@augure/skills": "0.1.0"
46
+ "tsup": "^8.5.1"
38
47
  },
39
48
  "keywords": [
40
49
  "ai",
@@ -52,14 +61,5 @@
52
61
  },
53
62
  "publishConfig": {
54
63
  "access": "public"
55
- },
56
- "scripts": {
57
- "build": "tsup",
58
- "dev": "tsup --watch",
59
- "test": "vitest run",
60
- "test:unit": "vitest run",
61
- "typecheck": "tsc --noEmit",
62
- "lint": "eslint src/",
63
- "clean": "rm -rf dist .turbo"
64
64
  }
65
- }
65
+ }