@stjbrown/agent-knowledge 0.1.0-beta.4 → 0.1.0-beta.5

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.
@@ -59,13 +59,237 @@ function bundledSkillsDir() {
59
59
  return resolve(here, "..", "..", "..", "..", "skills");
60
60
  }
61
61
 
62
+ // src/observability/config.ts
63
+ import { z } from "zod";
64
+
65
+ // src/observability/types.ts
66
+ var OBSERVABILITY_CAPTURE_MODES = ["off", "metadata", "full"];
67
+ var OBSERVABILITY_REMOTE_KINDS = ["phoenix", "otlp"];
68
+
69
+ // src/observability/config.ts
70
+ var DEFAULT_OBSERVABILITY_SETTINGS = {
71
+ capture: "off",
72
+ sampleRate: 1,
73
+ local: {
74
+ enabled: false,
75
+ retentionDays: 7
76
+ }
77
+ };
78
+ var captureModeSchema = z.enum(OBSERVABILITY_CAPTURE_MODES);
79
+ var remoteKindSchema = z.enum(OBSERVABILITY_REMOTE_KINDS);
80
+ var persistedEndpointSchema = z.string().min(1).refine((value) => {
81
+ try {
82
+ const url = new URL(value);
83
+ return (url.protocol === "http:" || url.protocol === "https:") && !url.username && !url.password && !url.search && !url.hash;
84
+ } catch {
85
+ return false;
86
+ }
87
+ });
88
+ var observabilitySettingsSchema = z.object({
89
+ capture: captureModeSchema,
90
+ sampleRate: z.number().min(0).max(1).optional(),
91
+ local: z.object({
92
+ enabled: z.boolean(),
93
+ retentionDays: z.number().int().min(1).max(3650).optional()
94
+ }).optional(),
95
+ remote: z.object({
96
+ kind: remoteKindSchema,
97
+ endpoint: persistedEndpointSchema,
98
+ projectName: z.string().min(1).optional()
99
+ }).optional()
100
+ });
101
+ function normalizeObservabilitySettings(value) {
102
+ if (value === void 0) return void 0;
103
+ const parsed = observabilitySettingsSchema.safeParse(value);
104
+ return parsed.success ? parsed.data : void 0;
105
+ }
106
+ function enumValue(value, allowed) {
107
+ const normalized = value?.trim().toLowerCase();
108
+ return normalized && allowed.includes(normalized) ? normalized : void 0;
109
+ }
110
+ function numberValue(value) {
111
+ if (value === void 0 || value.trim() === "") return void 0;
112
+ const parsed = Number(value);
113
+ return Number.isFinite(parsed) ? parsed : void 0;
114
+ }
115
+ function validHttpEndpoint(value) {
116
+ try {
117
+ const url = new URL(value);
118
+ return url.protocol === "http:" || url.protocol === "https:";
119
+ } catch {
120
+ return false;
121
+ }
122
+ }
123
+ function decodeHeaderValue(value) {
124
+ try {
125
+ return decodeURIComponent(value);
126
+ } catch {
127
+ return value;
128
+ }
129
+ }
130
+ function parseOtelHeaders(value) {
131
+ if (!value?.trim()) return {};
132
+ const headers = {};
133
+ for (const item of value.split(",")) {
134
+ const separator = item.indexOf("=");
135
+ if (separator <= 0) continue;
136
+ const key = item.slice(0, separator).trim();
137
+ const rawValue = item.slice(separator + 1).trim();
138
+ if (key) headers[key] = decodeHeaderValue(rawValue);
139
+ }
140
+ return headers;
141
+ }
142
+ function remoteFromEnvironment(kind, env, saved) {
143
+ const endpoint = kind === "phoenix" ? env["PHOENIX_COLLECTOR_ENDPOINT"]?.trim() || env["OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"]?.trim() || env["OTEL_EXPORTER_OTLP_ENDPOINT"]?.trim() || saved?.endpoint || "http://localhost:6006" : env["OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"]?.trim() || env["OTEL_EXPORTER_OTLP_ENDPOINT"]?.trim() || saved?.endpoint;
144
+ if (!endpoint) return void 0;
145
+ const projectName = kind === "phoenix" ? env["PHOENIX_PROJECT_NAME"]?.trim() || saved?.projectName || "janet" : saved?.projectName;
146
+ const headers = parseOtelHeaders(env["OTEL_EXPORTER_OTLP_HEADERS"]);
147
+ const hasProjectHeader = Object.keys(headers).some(
148
+ (key) => key.toLowerCase() === "x-project-name"
149
+ );
150
+ if (kind === "phoenix" && projectName && !hasProjectHeader) {
151
+ headers["x-project-name"] = projectName;
152
+ }
153
+ return {
154
+ kind,
155
+ endpoint,
156
+ ...projectName ? { projectName } : {},
157
+ headers
158
+ };
159
+ }
160
+ function resolveObservabilityConfig(saved, env = process.env) {
161
+ const warnings = [];
162
+ const savedSettings = saved ?? DEFAULT_OBSERVABILITY_SETTINGS;
163
+ const captureEnv = enumValue(env["JANET_OBSERVABILITY"], OBSERVABILITY_CAPTURE_MODES);
164
+ if (env["JANET_OBSERVABILITY"] && !captureEnv) {
165
+ warnings.push(
166
+ "Ignoring invalid JANET_OBSERVABILITY value; use off, metadata, or full."
167
+ );
168
+ }
169
+ const capture = captureEnv ?? savedSettings.capture;
170
+ const rateEnv = numberValue(env["JANET_OBSERVABILITY_SAMPLE_RATE"]);
171
+ if (env["JANET_OBSERVABILITY_SAMPLE_RATE"] !== void 0 && (rateEnv === void 0 || rateEnv < 0 || rateEnv > 1)) {
172
+ warnings.push("Ignoring invalid JANET_OBSERVABILITY_SAMPLE_RATE; use a value from 0 to 1.");
173
+ }
174
+ const sampleRate = rateEnv !== void 0 && rateEnv >= 0 && rateEnv <= 1 ? rateEnv : savedSettings.sampleRate ?? 1;
175
+ let local = {
176
+ enabled: savedSettings.local?.enabled ?? false,
177
+ retentionDays: savedSettings.local?.retentionDays ?? 7
178
+ };
179
+ let remote;
180
+ let explicitRemoteBackend = false;
181
+ const backendEnv = enumValue(
182
+ env["JANET_OBSERVABILITY_BACKEND"],
183
+ ["local", ...OBSERVABILITY_REMOTE_KINDS]
184
+ );
185
+ if (env["JANET_OBSERVABILITY_BACKEND"] && !backendEnv) {
186
+ warnings.push(
187
+ "Ignoring invalid JANET_OBSERVABILITY_BACKEND value; use local, phoenix, or otlp."
188
+ );
189
+ }
190
+ if (backendEnv === "local") {
191
+ local = { ...local, enabled: true };
192
+ } else if (backendEnv === "phoenix" || backendEnv === "otlp") {
193
+ explicitRemoteBackend = true;
194
+ local = { ...local, enabled: false };
195
+ remote = remoteFromEnvironment(backendEnv, env, savedSettings.remote);
196
+ } else if (savedSettings.remote) {
197
+ remote = remoteFromEnvironment(savedSettings.remote.kind, env, savedSettings.remote);
198
+ } else if (capture !== "off" && env["PHOENIX_COLLECTOR_ENDPOINT"]) {
199
+ remote = remoteFromEnvironment("phoenix", env);
200
+ local = { ...local, enabled: false };
201
+ } else if (capture !== "off" && (env["OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"] || env["OTEL_EXPORTER_OTLP_ENDPOINT"])) {
202
+ remote = remoteFromEnvironment("otlp", env);
203
+ local = { ...local, enabled: false };
204
+ }
205
+ if (remote && !validHttpEndpoint(remote.endpoint)) {
206
+ warnings.push("The observability endpoint is not a valid HTTP(S) URL.");
207
+ remote = void 0;
208
+ }
209
+ if (capture !== "off" && !local.enabled && !remote && !explicitRemoteBackend) {
210
+ local = { ...local, enabled: true };
211
+ }
212
+ if (capture !== "off" && explicitRemoteBackend && !remote) {
213
+ warnings.push("The selected remote observability backend has no endpoint.");
214
+ }
215
+ const enabled = capture !== "off" && (local.enabled || remote !== void 0);
216
+ return {
217
+ enabled,
218
+ capture,
219
+ sampleRate,
220
+ local: enabled ? local : { ...local, enabled: false },
221
+ ...enabled && remote ? { remote } : {},
222
+ warnings
223
+ };
224
+ }
225
+
226
+ // src/onboarding/settings.ts
227
+ import { mkdirSync as mkdirSync2, readFileSync, writeFileSync } from "fs";
228
+ import { dirname as dirname2, join as join2 } from "path";
229
+ var ONBOARDING_VERSION = 1;
230
+ function settingsPath() {
231
+ return join2(appDataDir(), "settings.json");
232
+ }
233
+ function loadSettings() {
234
+ try {
235
+ const value = JSON.parse(readFileSync(settingsPath(), "utf-8"));
236
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return {};
237
+ const raw = value;
238
+ const settings = {};
239
+ if (typeof raw["onboarding"] === "object" && raw["onboarding"] !== null && !Array.isArray(raw["onboarding"])) {
240
+ const onboarding = raw["onboarding"];
241
+ if (typeof onboarding["completedAt"] === "string" && typeof onboarding["version"] === "number") {
242
+ settings.onboarding = {
243
+ completedAt: onboarding["completedAt"],
244
+ version: onboarding["version"]
245
+ };
246
+ }
247
+ }
248
+ if (typeof raw["defaultModelId"] === "string") {
249
+ settings.defaultModelId = raw["defaultModelId"];
250
+ }
251
+ if (Array.isArray(raw["customModels"]) && raw["customModels"].every((model) => typeof model === "string")) {
252
+ settings.customModels = raw["customModels"];
253
+ }
254
+ const observability = normalizeObservabilitySettings(raw["observability"]);
255
+ if (observability) settings.observability = observability;
256
+ return settings;
257
+ } catch {
258
+ return {};
259
+ }
260
+ }
261
+ function saveSettings(settings) {
262
+ const p = settingsPath();
263
+ mkdirSync2(dirname2(p), { recursive: true });
264
+ writeFileSync(p, JSON.stringify(settings, null, 2) + "\n", "utf-8");
265
+ }
266
+ function completeOnboarding(modelId, stampedAt) {
267
+ const settings = loadSettings();
268
+ settings.defaultModelId = modelId;
269
+ settings.onboarding = { completedAt: stampedAt, version: ONBOARDING_VERSION };
270
+ saveSettings(settings);
271
+ }
272
+ function rememberModel(modelId) {
273
+ const id = modelId.trim();
274
+ if (!id) return;
275
+ const settings = loadSettings();
276
+ const rest = (settings.customModels ?? []).filter((m) => m !== id);
277
+ settings.customModels = [id, ...rest].slice(0, 20);
278
+ saveSettings(settings);
279
+ }
280
+ function rememberObservability(observability) {
281
+ const settings = loadSettings();
282
+ settings.observability = observability;
283
+ saveSettings(settings);
284
+ }
285
+
62
286
  // src/gateways/oauth/claude-max.ts
63
287
  import { createAnthropic } from "@ai-sdk/anthropic";
64
288
  import { wrapLanguageModel } from "ai";
65
289
 
66
290
  // src/auth/storage.ts
67
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync, writeFileSync, chmodSync } from "fs";
68
- import { dirname as dirname2, join as join2 } from "path";
291
+ import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2, chmodSync } from "fs";
292
+ import { dirname as dirname3, join as join3 } from "path";
69
293
 
70
294
  // src/auth/authorization-input.ts
71
295
  function parseAuthorizationInput(input) {
@@ -739,7 +963,7 @@ function getOAuthProvider(id) {
739
963
  return oauthProviderRegistry.get(id);
740
964
  }
741
965
  var AuthStorage = class {
742
- constructor(authPath = join2(appDataDir(), "auth.json")) {
966
+ constructor(authPath = join3(appDataDir(), "auth.json")) {
743
967
  this.authPath = authPath;
744
968
  this.reload();
745
969
  }
@@ -754,7 +978,7 @@ var AuthStorage = class {
754
978
  return;
755
979
  }
756
980
  try {
757
- this.data = JSON.parse(readFileSync(this.authPath, "utf-8"));
981
+ this.data = JSON.parse(readFileSync2(this.authPath, "utf-8"));
758
982
  } catch {
759
983
  this.data = {};
760
984
  }
@@ -763,11 +987,11 @@ var AuthStorage = class {
763
987
  * Save credentials to disk.
764
988
  */
765
989
  save() {
766
- const dir = dirname2(this.authPath);
990
+ const dir = dirname3(this.authPath);
767
991
  if (!existsSync2(dir)) {
768
- mkdirSync2(dir, { recursive: true, mode: 448 });
992
+ mkdirSync3(dir, { recursive: true, mode: 448 });
769
993
  }
770
- writeFileSync(this.authPath, JSON.stringify(this.data, null, 2), "utf-8");
994
+ writeFileSync2(this.authPath, JSON.stringify(this.data, null, 2), "utf-8");
771
995
  chmodSync(this.authPath, 384);
772
996
  }
773
997
  /**
@@ -1075,18 +1299,226 @@ Never repeat a tool call that already failed the same way. If fetching or scrapi
1075
1299
  Answer from the bundle. When you state something the bundle records, cite the concept it came from. If the bundle doesn't cover something, say so plainly rather than guessing \u2014 "I don't have that in the bundle yet, but I can ingest a source about it."`;
1076
1300
  var GREETING = "Hi there! I'm Janet.";
1077
1301
 
1302
+ // src/version.ts
1303
+ import { readFileSync as readFileSync3 } from "fs";
1304
+ var packageJsonUrl = new URL("../package.json", import.meta.url);
1305
+ function packageVersion() {
1306
+ const metadata = JSON.parse(readFileSync3(packageJsonUrl, "utf8"));
1307
+ if (typeof metadata !== "object" || metadata === null || !("version" in metadata) || typeof metadata.version !== "string") {
1308
+ throw new Error("Janet's package metadata does not contain a version");
1309
+ }
1310
+ return metadata.version;
1311
+ }
1312
+
1313
+ // src/observability/runtime.ts
1314
+ import { SpanType } from "@mastra/core/observability";
1315
+ import {
1316
+ MastraStorageExporter,
1317
+ Observability,
1318
+ SamplingStrategyType
1319
+ } from "@mastra/observability";
1320
+ import { OtelExporter } from "@mastra/otel-exporter";
1321
+
1322
+ // src/agent/storage.ts
1323
+ import { join as join4 } from "path";
1324
+ import { LibSQLStore } from "@mastra/libsql";
1325
+ import { MastraCompositeStore } from "@mastra/core/storage";
1326
+ function observabilityDbPath(globalConfigDir) {
1327
+ return join4(globalConfigDir, "observability.db");
1328
+ }
1329
+ var JanetCompositeStorage = class extends MastraCompositeStore {
1330
+ constructor(threadStore, observabilityStore, retentionDays) {
1331
+ super({
1332
+ id: "agent-knowledge-storage",
1333
+ default: threadStore,
1334
+ domains: {
1335
+ observability: observabilityStore.stores.observability
1336
+ },
1337
+ retention: {
1338
+ observability: {
1339
+ spans: { maxAge: `${retentionDays}d` }
1340
+ }
1341
+ }
1342
+ });
1343
+ this.threadStore = threadStore;
1344
+ this.observabilityStore = observabilityStore;
1345
+ }
1346
+ threadStore;
1347
+ observabilityStore;
1348
+ async close() {
1349
+ const results = await Promise.allSettled([
1350
+ this.threadStore.close(),
1351
+ this.observabilityStore.close()
1352
+ ]);
1353
+ const failure = results.find(
1354
+ (result) => result.status === "rejected"
1355
+ );
1356
+ if (failure) throw failure.reason;
1357
+ }
1358
+ };
1359
+ function createStorage(globalConfigDir, options = {}) {
1360
+ ensureDir(globalConfigDir);
1361
+ const threadStore = new LibSQLStore({
1362
+ id: "agent-knowledge-threads",
1363
+ url: `file:${join4(globalConfigDir, "threads.db")}`
1364
+ });
1365
+ if (!options.localObservability?.enabled) return threadStore;
1366
+ const observabilityStore = new LibSQLStore({
1367
+ id: "agent-knowledge-observability",
1368
+ url: `file:${observabilityDbPath(globalConfigDir)}`
1369
+ });
1370
+ return new JanetCompositeStorage(
1371
+ threadStore,
1372
+ observabilityStore,
1373
+ options.localObservability.retentionDays
1374
+ );
1375
+ }
1376
+
1377
+ // src/observability/runtime.ts
1378
+ function safeObservabilityEndpoint(endpoint) {
1379
+ try {
1380
+ const url = new URL(endpoint);
1381
+ url.username = "";
1382
+ url.password = "";
1383
+ url.search = "";
1384
+ url.hash = "";
1385
+ return url.toString().replace(/\/$/, "");
1386
+ } catch {
1387
+ return "(invalid endpoint)";
1388
+ }
1389
+ }
1390
+ function statusFor(config) {
1391
+ const destinations = [];
1392
+ if (config.local.enabled) destinations.push("local");
1393
+ if (config.remote) {
1394
+ destinations.push(
1395
+ config.remote.kind === "phoenix" ? `phoenix (${safeObservabilityEndpoint(config.remote.endpoint)})` : `otlp (${safeObservabilityEndpoint(config.remote.endpoint)})`
1396
+ );
1397
+ }
1398
+ return {
1399
+ enabled: config.enabled,
1400
+ capture: config.capture,
1401
+ sampleRate: config.sampleRate,
1402
+ destinations,
1403
+ warnings: [...config.warnings]
1404
+ };
1405
+ }
1406
+ function formatObservabilityStatus(status) {
1407
+ if (!status.enabled) {
1408
+ return status.warnings.length ? `off (${status.warnings.join(" ")})` : "off";
1409
+ }
1410
+ const sample = status.sampleRate === 1 ? "" : `, ${Math.round(status.sampleRate * 100)}% sampling`;
1411
+ return `${status.capture} to ${status.destinations.join(" + ")}${sample}`;
1412
+ }
1413
+ function createObservabilityRuntime(globalConfigDir, config) {
1414
+ const storage = createStorage(globalConfigDir, {
1415
+ localObservability: config.local
1416
+ });
1417
+ let observability;
1418
+ if (config.enabled) {
1419
+ const exporters = [];
1420
+ if (config.local.enabled) {
1421
+ exporters.push(
1422
+ new MastraStorageExporter({
1423
+ maxBatchSize: 50,
1424
+ maxBufferSize: 500,
1425
+ maxBatchWaitMs: 1e3,
1426
+ strategy: "auto"
1427
+ })
1428
+ );
1429
+ }
1430
+ if (config.remote) {
1431
+ exporters.push(
1432
+ new OtelExporter({
1433
+ provider: {
1434
+ custom: {
1435
+ endpoint: config.remote.endpoint,
1436
+ protocol: "http/protobuf",
1437
+ headers: config.remote.headers
1438
+ }
1439
+ },
1440
+ signals: {
1441
+ traces: true,
1442
+ logs: false
1443
+ },
1444
+ timeout: 1e4,
1445
+ batchSize: 50,
1446
+ resourceAttributes: config.remote.kind === "phoenix" && config.remote.projectName ? { "openinference.project.name": config.remote.projectName } : void 0
1447
+ })
1448
+ );
1449
+ }
1450
+ observability = new Observability({
1451
+ configs: {
1452
+ janet: {
1453
+ serviceName: "janet",
1454
+ sampling: config.sampleRate === 1 ? { type: SamplingStrategyType.ALWAYS } : {
1455
+ type: SamplingStrategyType.RATIO,
1456
+ probability: config.sampleRate
1457
+ },
1458
+ exporters,
1459
+ includeInternalSpans: false,
1460
+ excludeSpanTypes: [SpanType.MODEL_CHUNK],
1461
+ requestContextKeys: [],
1462
+ serializationOptions: {
1463
+ maxStringLength: 2e3,
1464
+ maxDepth: 5,
1465
+ maxArrayLength: 50,
1466
+ maxObjectKeys: 50
1467
+ },
1468
+ logging: {
1469
+ enabled: false
1470
+ }
1471
+ }
1472
+ },
1473
+ sensitiveDataFilter: true
1474
+ });
1475
+ }
1476
+ return {
1477
+ config,
1478
+ status: statusFor(config),
1479
+ observability,
1480
+ storage,
1481
+ tracingOptionsForTurn(context) {
1482
+ if (!config.enabled) return void 0;
1483
+ return {
1484
+ metadata: {
1485
+ "janet.version": packageVersion(),
1486
+ "janet.mode": context.interactive ? "interactive" : "headless",
1487
+ "janet.operation": context.operation,
1488
+ "janet.capture": config.capture,
1489
+ "janet.resource_id": context.resourceId,
1490
+ ...context.threadId ? { "janet.thread_id": context.threadId } : {}
1491
+ },
1492
+ tags: ["janet", context.operation],
1493
+ hideInput: config.capture !== "full",
1494
+ hideOutput: config.capture !== "full"
1495
+ };
1496
+ },
1497
+ async flush() {
1498
+ await observability?.flush();
1499
+ },
1500
+ async prune() {
1501
+ if (!config.local.enabled) return;
1502
+ await storage.prune({
1503
+ maxBatches: 1,
1504
+ maxRows: 1e3
1505
+ });
1506
+ }
1507
+ };
1508
+ }
1509
+
1078
1510
  // src/agent/controller.ts
1079
1511
  import { AgentController } from "@mastra/core/agent-controller";
1080
- import { z } from "zod";
1512
+ import { z as z2 } from "zod";
1081
1513
 
1082
1514
  // src/agent/agent.ts
1083
1515
  import { Agent } from "@mastra/core/agent";
1084
1516
  import { Memory } from "@mastra/memory";
1085
1517
 
1086
1518
  // src/gateways/vertex.ts
1087
- import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
1519
+ import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
1088
1520
  import { homedir as homedir2 } from "os";
1089
- import { join as join3 } from "path";
1521
+ import { join as join5 } from "path";
1090
1522
  import { createVertex } from "@ai-sdk/google-vertex";
1091
1523
  import { createVertexAnthropic } from "@ai-sdk/google-vertex/anthropic";
1092
1524
  import { wrapLanguageModel as wrapLanguageModel2 } from "ai";
@@ -1097,13 +1529,13 @@ function hasGoogleCredentials() {
1097
1529
  return true;
1098
1530
  }
1099
1531
  const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir2();
1100
- return existsSync3(join3(home, ".config", "gcloud", "application_default_credentials.json"));
1532
+ return existsSync3(join5(home, ".config", "gcloud", "application_default_credentials.json"));
1101
1533
  }
1102
1534
  function adcQuotaProject() {
1103
1535
  const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir2();
1104
- const adcPath = join3(home, ".config", "gcloud", "application_default_credentials.json");
1536
+ const adcPath = join5(home, ".config", "gcloud", "application_default_credentials.json");
1105
1537
  try {
1106
- const adc = JSON.parse(readFileSync2(adcPath, "utf-8"));
1538
+ const adc = JSON.parse(readFileSync4(adcPath, "utf-8"));
1107
1539
  return adc.quota_project_id || void 0;
1108
1540
  } catch {
1109
1541
  return void 0;
@@ -1200,7 +1632,7 @@ function createVertexGateway() {
1200
1632
  // src/gateways/bedrock.ts
1201
1633
  import { existsSync as existsSync4 } from "fs";
1202
1634
  import { homedir as homedir3 } from "os";
1203
- import { join as join4 } from "path";
1635
+ import { join as join6 } from "path";
1204
1636
  import { createAmazonBedrock } from "@ai-sdk/amazon-bedrock";
1205
1637
  import { fromNodeProviderChain } from "@aws-sdk/credential-providers";
1206
1638
  import { MastraModelGateway as MastraModelGateway2 } from "@mastra/core/llm";
@@ -1211,9 +1643,9 @@ function hasAwsCredentials() {
1211
1643
  }
1212
1644
  const home = process.env["HOME"] || process.env["USERPROFILE"] || homedir3();
1213
1645
  if (home) {
1214
- const awsDir = join4(home, ".aws");
1215
- const credentialsPath = process.env["AWS_SHARED_CREDENTIALS_FILE"] ?? join4(awsDir, "credentials");
1216
- const configPath = process.env["AWS_CONFIG_FILE"] ?? join4(awsDir, "config");
1646
+ const awsDir = join6(home, ".aws");
1647
+ const credentialsPath = process.env["AWS_SHARED_CREDENTIALS_FILE"] ?? join6(awsDir, "credentials");
1648
+ const configPath = process.env["AWS_CONFIG_FILE"] ?? join6(awsDir, "config");
1217
1649
  if (existsSync4(credentialsPath) || existsSync4(configPath)) return true;
1218
1650
  }
1219
1651
  return false;
@@ -1604,15 +2036,6 @@ function createJanetAgent(opts) {
1604
2036
  });
1605
2037
  }
1606
2038
 
1607
- // src/agent/storage.ts
1608
- import { join as join5 } from "path";
1609
- import { LibSQLStore } from "@mastra/libsql";
1610
- function createStorage(globalConfigDir) {
1611
- ensureDir(globalConfigDir);
1612
- const dbPath = join5(globalConfigDir, "threads.db");
1613
- return new LibSQLStore({ id: "agent-knowledge-threads", url: `file:${dbPath}` });
1614
- }
1615
-
1616
2039
  // src/agent/workspace.ts
1617
2040
  import {
1618
2041
  LocalFilesystem,
@@ -1879,19 +2302,19 @@ function attachHerdrReporter(session, opts) {
1879
2302
  }
1880
2303
 
1881
2304
  // src/agent/controller.ts
1882
- var policy = z.enum(["allow", "ask", "deny"]);
1883
- var permissionRules = z.object({
1884
- categories: z.record(z.string(), policy),
1885
- tools: z.record(z.string(), policy)
2305
+ var policy = z2.enum(["allow", "ask", "deny"]);
2306
+ var permissionRules = z2.object({
2307
+ categories: z2.record(z2.string(), policy),
2308
+ tools: z2.record(z2.string(), policy)
1886
2309
  });
1887
- var stateSchema = z.object({
1888
- projectPath: z.string(),
1889
- bundlePath: z.string(),
1890
- configDir: z.string(),
2310
+ var stateSchema = z2.object({
2311
+ projectPath: z2.string(),
2312
+ bundlePath: z2.string(),
2313
+ configDir: z2.string(),
1891
2314
  // Core's approval gate reads `state.yolo === true`. Janet enables normal
1892
2315
  // in-loop tool execution and puts approval on the dangerous tools themselves;
1893
2316
  // denied headless categories are still removed from the active tool set.
1894
- yolo: z.boolean(),
2317
+ yolo: z2.boolean(),
1895
2318
  // Tool-approval rules by category/tool. Must be in the schema or session state
1896
2319
  // strips it, and setForCategory / getRules silently no-op.
1897
2320
  permissionRules: permissionRules.optional()
@@ -1919,7 +2342,12 @@ async function resumeThread(session, threadId) {
1919
2342
  }
1920
2343
  async function bootJanet(opts) {
1921
2344
  const paths = resolveProjectPaths({ dir: opts.dir, bundle: opts.bundle });
1922
- const storage = createStorage(paths.globalConfigDir);
2345
+ const observabilityConfig = resolveObservabilityConfig(loadSettings().observability);
2346
+ const observability = createObservabilityRuntime(
2347
+ paths.globalConfigDir,
2348
+ observabilityConfig
2349
+ );
2350
+ const storage = observability.storage;
1923
2351
  const skills = ensureSkillLinks(paths.projectPath);
1924
2352
  const workspace = createWorkspace({
1925
2353
  projectPath: paths.projectPath,
@@ -1952,16 +2380,19 @@ async function bootJanet(opts) {
1952
2380
  yolo: true,
1953
2381
  permissionRules: permissionRulesFor(opts)
1954
2382
  },
1955
- workspace: () => workspace
2383
+ workspace: () => workspace,
2384
+ ...observability.observability ? { observability: observability.observability } : {}
1956
2385
  });
1957
2386
  await controller.init();
2387
+ await observability.prune().catch(() => {
2388
+ });
1958
2389
  const session = await controller.createSession({
1959
2390
  resourceId: paths.resourceId,
1960
2391
  ownerId: paths.ownerId
1961
2392
  });
1962
2393
  await resumeThread(session, opts.threadId);
1963
2394
  const herdrDetach = attachHerdrReporter(session, { projectPath: paths.projectPath });
1964
- return { controller, session, paths, herdrDetach };
2395
+ return { controller, session, paths, herdrDetach, observability };
1965
2396
  }
1966
2397
 
1967
2398
  // src/headless/format.ts
@@ -2001,13 +2432,20 @@ function messageToolNames(message) {
2001
2432
 
2002
2433
  export {
2003
2434
  resolveProjectPaths,
2004
- appDataDir,
2435
+ resolveObservabilityConfig,
2436
+ loadSettings,
2437
+ completeOnboarding,
2438
+ rememberModel,
2439
+ rememberObservability,
2005
2440
  hasGoogleCredentials,
2006
2441
  hasAwsCredentials,
2007
2442
  getAuthStorage,
2008
2443
  GREETING,
2444
+ packageVersion,
2445
+ safeObservabilityEndpoint,
2446
+ formatObservabilityStatus,
2009
2447
  bootJanet,
2010
2448
  messageText,
2011
2449
  messageToolNames
2012
2450
  };
2013
- //# sourceMappingURL=chunk-H4H6S4AV.js.map
2451
+ //# sourceMappingURL=chunk-EBMACGJV.js.map