@stjbrown/agent-knowledge 0.1.0-beta.3 → 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.
- package/OBSERVABILITY.md +163 -0
- package/README.md +29 -1
- package/dist/{chunk-H4H6S4AV.js → chunk-EBMACGJV.js} +478 -40
- package/dist/chunk-EBMACGJV.js.map +1 -0
- package/dist/{chunk-RDL2AHSN.js → chunk-GWV4DABI.js} +16 -4
- package/dist/chunk-GWV4DABI.js.map +1 -0
- package/dist/{chunk-PBRTNSWS.js → chunk-PUTDZMUI.js} +4 -41
- package/dist/chunk-PUTDZMUI.js.map +1 -0
- package/dist/headless.js +2 -2
- package/dist/index.js +2 -2
- package/dist/main.js +7 -16
- package/dist/main.js.map +1 -1
- package/dist/{tui-GCLV5CZQ.js → tui-6F3IBI3J.js} +467 -44
- package/dist/tui-6F3IBI3J.js.map +1 -0
- package/package.json +6 -2
- package/skills/kb/SKILL.md +5 -0
- package/skills/kb/example-bundle/spec/types.md +3 -2
- package/skills/kb-ingest/SKILL.md +21 -3
- package/skills/kb-init/SKILL.md +16 -5
- package/skills/kb-lint/SKILL.md +6 -1
- package/dist/chunk-H4H6S4AV.js.map +0 -1
- package/dist/chunk-PBRTNSWS.js.map +0 -1
- package/dist/chunk-RDL2AHSN.js.map +0 -1
- package/dist/tui-GCLV5CZQ.js.map +0 -1
|
@@ -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
|
|
68
|
-
import { dirname as
|
|
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 =
|
|
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(
|
|
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 =
|
|
990
|
+
const dir = dirname3(this.authPath);
|
|
767
991
|
if (!existsSync2(dir)) {
|
|
768
|
-
|
|
992
|
+
mkdirSync3(dir, { recursive: true, mode: 448 });
|
|
769
993
|
}
|
|
770
|
-
|
|
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
|
|
1519
|
+
import { existsSync as existsSync3, readFileSync as readFileSync4 } from "fs";
|
|
1088
1520
|
import { homedir as homedir2 } from "os";
|
|
1089
|
-
import { join as
|
|
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(
|
|
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 =
|
|
1536
|
+
const adcPath = join5(home, ".config", "gcloud", "application_default_credentials.json");
|
|
1105
1537
|
try {
|
|
1106
|
-
const adc = JSON.parse(
|
|
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
|
|
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 =
|
|
1215
|
-
const credentialsPath = process.env["AWS_SHARED_CREDENTIALS_FILE"] ??
|
|
1216
|
-
const configPath = process.env["AWS_CONFIG_FILE"] ??
|
|
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 =
|
|
1883
|
-
var permissionRules =
|
|
1884
|
-
categories:
|
|
1885
|
-
tools:
|
|
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 =
|
|
1888
|
-
projectPath:
|
|
1889
|
-
bundlePath:
|
|
1890
|
-
configDir:
|
|
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:
|
|
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
|
|
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
|
-
|
|
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-
|
|
2451
|
+
//# sourceMappingURL=chunk-EBMACGJV.js.map
|