@axiom-lattice/gateway 2.1.19 → 2.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1319,6 +1319,311 @@ async function getHealth(request, reply) {
1319
1319
  }
1320
1320
  }
1321
1321
 
1322
+ // src/controllers/skills.ts
1323
+ import { getStoreLattice as getStoreLattice3 } from "@axiom-lattice/core";
1324
+ import { validateSkillName } from "@axiom-lattice/core";
1325
+ function serializeSkill(skill) {
1326
+ const serialized = {
1327
+ id: skill.id,
1328
+ name: skill.name,
1329
+ description: skill.description,
1330
+ license: skill.license,
1331
+ compatibility: skill.compatibility,
1332
+ metadata: skill.metadata || {},
1333
+ content: skill.content,
1334
+ subSkills: skill.subSkills,
1335
+ createdAt: skill.createdAt instanceof Date ? skill.createdAt.toISOString() : skill.createdAt ? new Date(skill.createdAt).toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
1336
+ updatedAt: skill.updatedAt instanceof Date ? skill.updatedAt.toISOString() : skill.updatedAt ? new Date(skill.updatedAt).toISOString() : (/* @__PURE__ */ new Date()).toISOString()
1337
+ };
1338
+ Object.keys(serialized).forEach((key) => {
1339
+ if (serialized[key] === void 0) {
1340
+ delete serialized[key];
1341
+ }
1342
+ });
1343
+ return serialized;
1344
+ }
1345
+ async function getSkillList(request, reply) {
1346
+ try {
1347
+ const storeLattice = getStoreLattice3("default", "skill");
1348
+ const skillStore = storeLattice.store;
1349
+ const skills = await skillStore.getAllSkills();
1350
+ const serializedSkills = skills.map(serializeSkill);
1351
+ return {
1352
+ success: true,
1353
+ message: "Successfully retrieved skill list",
1354
+ data: {
1355
+ records: serializedSkills,
1356
+ total: serializedSkills.length
1357
+ }
1358
+ };
1359
+ } catch (error) {
1360
+ return reply.status(500).send({
1361
+ success: false,
1362
+ message: `Failed to retrieve skills: ${error.message}`,
1363
+ data: {
1364
+ records: [],
1365
+ total: 0
1366
+ }
1367
+ });
1368
+ }
1369
+ }
1370
+ async function getSkill(request, reply) {
1371
+ try {
1372
+ const { id } = request.params;
1373
+ const storeLattice = getStoreLattice3("default", "skill");
1374
+ const skillStore = storeLattice.store;
1375
+ const skill = await skillStore.getSkillById(id);
1376
+ if (!skill) {
1377
+ return reply.status(404).send({
1378
+ success: false,
1379
+ message: "Skill not found"
1380
+ });
1381
+ }
1382
+ return {
1383
+ success: true,
1384
+ message: "Successfully retrieved skill",
1385
+ data: serializeSkill(skill)
1386
+ };
1387
+ } catch (error) {
1388
+ return reply.status(500).send({
1389
+ success: false,
1390
+ message: `Failed to retrieve skill: ${error.message}`
1391
+ });
1392
+ }
1393
+ }
1394
+ async function createSkill(request, reply) {
1395
+ try {
1396
+ const data = request.body;
1397
+ if (!data.name) {
1398
+ return reply.status(400).send({
1399
+ success: false,
1400
+ message: "name is required"
1401
+ });
1402
+ }
1403
+ if (!data.description) {
1404
+ return reply.status(400).send({
1405
+ success: false,
1406
+ message: "description is required"
1407
+ });
1408
+ }
1409
+ try {
1410
+ validateSkillName(data.name);
1411
+ } catch (error) {
1412
+ return reply.status(400).send({
1413
+ success: false,
1414
+ message: error.message || "Invalid skill name format"
1415
+ });
1416
+ }
1417
+ const id = request.body.id || data.name;
1418
+ if (id !== data.name) {
1419
+ return reply.status(400).send({
1420
+ success: false,
1421
+ message: `id "${id}" must equal name "${data.name}" (name is used for path addressing)`
1422
+ });
1423
+ }
1424
+ const storeLattice = getStoreLattice3("default", "skill");
1425
+ const skillStore = storeLattice.store;
1426
+ const exists = await skillStore.hasSkill(id);
1427
+ if (exists) {
1428
+ return reply.status(409).send({
1429
+ success: false,
1430
+ message: `Skill with id "${id}" already exists`
1431
+ });
1432
+ }
1433
+ const newSkill = await skillStore.createSkill(id, data);
1434
+ return reply.status(201).send({
1435
+ success: true,
1436
+ message: "Successfully created skill",
1437
+ data: serializeSkill(newSkill)
1438
+ });
1439
+ } catch (error) {
1440
+ return reply.status(500).send({
1441
+ success: false,
1442
+ message: `Failed to create skill: ${error.message}`
1443
+ });
1444
+ }
1445
+ }
1446
+ async function updateSkill(request, reply) {
1447
+ try {
1448
+ const { id } = request.params;
1449
+ const updates = request.body;
1450
+ if (updates.name !== void 0) {
1451
+ try {
1452
+ validateSkillName(updates.name);
1453
+ } catch (error) {
1454
+ return reply.status(400).send({
1455
+ success: false,
1456
+ message: error.message || "Invalid skill name format"
1457
+ });
1458
+ }
1459
+ }
1460
+ const storeLattice = getStoreLattice3("default", "skill");
1461
+ const skillStore = storeLattice.store;
1462
+ const exists = await skillStore.hasSkill(id);
1463
+ if (!exists) {
1464
+ return reply.status(404).send({
1465
+ success: false,
1466
+ message: "Skill not found"
1467
+ });
1468
+ }
1469
+ const updatedSkill = await skillStore.updateSkill(id, updates);
1470
+ if (!updatedSkill) {
1471
+ return reply.status(500).send({
1472
+ success: false,
1473
+ message: "Failed to update skill"
1474
+ });
1475
+ }
1476
+ return {
1477
+ success: true,
1478
+ message: "Successfully updated skill",
1479
+ data: serializeSkill(updatedSkill)
1480
+ };
1481
+ } catch (error) {
1482
+ return reply.status(500).send({
1483
+ success: false,
1484
+ message: `Failed to update skill: ${error.message}`
1485
+ });
1486
+ }
1487
+ }
1488
+ async function deleteSkill(request, reply) {
1489
+ try {
1490
+ const { id } = request.params;
1491
+ const storeLattice = getStoreLattice3("default", "skill");
1492
+ const skillStore = storeLattice.store;
1493
+ const exists = await skillStore.hasSkill(id);
1494
+ if (!exists) {
1495
+ return reply.status(404).send({
1496
+ success: false,
1497
+ message: "Skill not found"
1498
+ });
1499
+ }
1500
+ const deleted = await skillStore.deleteSkill(id);
1501
+ if (!deleted) {
1502
+ return reply.status(500).send({
1503
+ success: false,
1504
+ message: "Failed to delete skill"
1505
+ });
1506
+ }
1507
+ return {
1508
+ success: true,
1509
+ message: "Successfully deleted skill"
1510
+ };
1511
+ } catch (error) {
1512
+ return reply.status(500).send({
1513
+ success: false,
1514
+ message: `Failed to delete skill: ${error.message}`
1515
+ });
1516
+ }
1517
+ }
1518
+ async function searchSkillsByMetadata(request, reply) {
1519
+ try {
1520
+ const { key, value } = request.query;
1521
+ if (!key || !value) {
1522
+ return reply.status(400).send({
1523
+ success: false,
1524
+ message: "key and value query parameters are required",
1525
+ data: {
1526
+ records: [],
1527
+ total: 0
1528
+ }
1529
+ });
1530
+ }
1531
+ const storeLattice = getStoreLattice3("default", "skill");
1532
+ const skillStore = storeLattice.store;
1533
+ const skills = await skillStore.searchByMetadata(key, value);
1534
+ const serializedSkills = skills.map(serializeSkill);
1535
+ return {
1536
+ success: true,
1537
+ message: "Successfully searched skills",
1538
+ data: {
1539
+ records: serializedSkills,
1540
+ total: serializedSkills.length
1541
+ }
1542
+ };
1543
+ } catch (error) {
1544
+ return reply.status(500).send({
1545
+ success: false,
1546
+ message: `Failed to search skills: ${error.message}`,
1547
+ data: {
1548
+ records: [],
1549
+ total: 0
1550
+ }
1551
+ });
1552
+ }
1553
+ }
1554
+ async function filterSkillsByCompatibility(request, reply) {
1555
+ try {
1556
+ const { compatibility } = request.query;
1557
+ if (!compatibility) {
1558
+ return reply.status(400).send({
1559
+ success: false,
1560
+ message: "compatibility query parameter is required",
1561
+ data: {
1562
+ records: [],
1563
+ total: 0
1564
+ }
1565
+ });
1566
+ }
1567
+ const storeLattice = getStoreLattice3("default", "skill");
1568
+ const skillStore = storeLattice.store;
1569
+ const skills = await skillStore.filterByCompatibility(compatibility);
1570
+ const serializedSkills = skills.map(serializeSkill);
1571
+ return {
1572
+ success: true,
1573
+ message: "Successfully filtered skills",
1574
+ data: {
1575
+ records: serializedSkills,
1576
+ total: serializedSkills.length
1577
+ }
1578
+ };
1579
+ } catch (error) {
1580
+ return reply.status(500).send({
1581
+ success: false,
1582
+ message: `Failed to filter skills: ${error.message}`,
1583
+ data: {
1584
+ records: [],
1585
+ total: 0
1586
+ }
1587
+ });
1588
+ }
1589
+ }
1590
+ async function filterSkillsByLicense(request, reply) {
1591
+ try {
1592
+ const { license } = request.query;
1593
+ if (!license) {
1594
+ return reply.status(400).send({
1595
+ success: false,
1596
+ message: "license query parameter is required",
1597
+ data: {
1598
+ records: [],
1599
+ total: 0
1600
+ }
1601
+ });
1602
+ }
1603
+ const storeLattice = getStoreLattice3("default", "skill");
1604
+ const skillStore = storeLattice.store;
1605
+ const skills = await skillStore.filterByLicense(license);
1606
+ const serializedSkills = skills.map(serializeSkill);
1607
+ return {
1608
+ success: true,
1609
+ message: "Successfully filtered skills",
1610
+ data: {
1611
+ records: serializedSkills,
1612
+ total: serializedSkills.length
1613
+ }
1614
+ };
1615
+ } catch (error) {
1616
+ return reply.status(500).send({
1617
+ success: false,
1618
+ message: `Failed to filter skills: ${error.message}`,
1619
+ data: {
1620
+ records: [],
1621
+ total: 0
1622
+ }
1623
+ });
1624
+ }
1625
+ }
1626
+
1322
1627
  // src/schemas/index.ts
1323
1628
  var getAllMemoryItemsSchema = {
1324
1629
  description: "Get all memory items for an assistant thread",
@@ -1678,144 +1983,35 @@ var registerLatticeRoutes = (app2) => {
1678
1983
  app2.post("/api/schedules/:taskId/cancel", cancelScheduledTask);
1679
1984
  app2.post("/api/schedules/:taskId/pause", pauseScheduledTask);
1680
1985
  app2.post("/api/schedules/:taskId/resume", resumeScheduledTask);
1681
- };
1682
-
1683
- // src/logger/Logger.ts
1684
- import pino from "pino";
1685
- import "pino-pretty";
1686
- import "pino-roll";
1687
- var PinoLoggerFactory = class _PinoLoggerFactory {
1688
- constructor() {
1689
- const isProd = process.env.NODE_ENV === "production";
1690
- const loggerConfig = {
1691
- // 自定义时间戳格式
1692
- timestamp: () => `,"@timestamp":"${(/* @__PURE__ */ new Date()).toISOString()}"`,
1693
- // 关闭默认的时间戳键
1694
- base: {
1695
- "@version": "1",
1696
- app_name: "lattice",
1697
- service_name: "lattice/graph-server",
1698
- thread_name: "main",
1699
- logger_name: "lattice-graph-logger"
1700
- },
1701
- formatters: {
1702
- level: (label, number) => {
1703
- return {
1704
- level: label.toUpperCase(),
1705
- level_value: number * 1e3
1706
- };
1707
- }
1708
- }
1709
- };
1710
- if (isProd) {
1711
- try {
1712
- this.pinoLogger = pino(
1713
- loggerConfig,
1714
- pino.transport({
1715
- target: "pino-roll",
1716
- options: {
1717
- file: "./logs/fin_ai_graph_server",
1718
- frequency: "daily",
1719
- mkdir: true
1720
- }
1721
- })
1722
- );
1723
- } catch (error) {
1724
- console.error(
1725
- "\u65E0\u6CD5\u521D\u59CB\u5316 pino-roll \u65E5\u5FD7\u8BB0\u5F55\u5668\uFF0C\u56DE\u9000\u5230\u63A7\u5236\u53F0\u65E5\u5FD7",
1726
- error
1727
- );
1728
- this.pinoLogger = pino({
1729
- ...loggerConfig,
1730
- transport: {
1731
- target: "pino-pretty",
1732
- options: {
1733
- colorize: true
1734
- }
1735
- }
1736
- });
1737
- }
1738
- } else {
1739
- this.pinoLogger = pino({
1740
- ...loggerConfig,
1741
- transport: {
1742
- target: "pino-pretty",
1743
- options: {
1744
- colorize: true
1745
- }
1746
- }
1747
- });
1748
- }
1749
- }
1750
- static getInstance() {
1751
- if (!_PinoLoggerFactory.instance) {
1752
- _PinoLoggerFactory.instance = new _PinoLoggerFactory();
1753
- }
1754
- return _PinoLoggerFactory.instance;
1755
- }
1756
- getPinoLogger() {
1757
- return this.pinoLogger;
1758
- }
1759
- };
1760
- var Logger = class _Logger {
1761
- constructor(options) {
1762
- this.context = options?.context || {};
1763
- this.name = options?.name || "lattice-graph-logger";
1764
- this.serviceName = options?.serviceName || "lattice/graph-server";
1765
- }
1766
- /**
1767
- * 获取合并了上下文的日志对象
1768
- * @param additionalContext 额外的上下文数据
1769
- * @returns 带有上下文的pino日志对象
1770
- */
1771
- getContextualLogger(additionalContext) {
1772
- const pinoLogger = PinoLoggerFactory.getInstance().getPinoLogger();
1773
- const contextObj = {
1774
- "x-user-id": this.context["x-user-id"] || "",
1775
- "x-tenant-id": this.context["x-tenant-id"] || "",
1776
- "x-request-id": this.context["x-request-id"] || "",
1777
- "x-task-id": this.context["x-task-id"] || "",
1778
- "x-thread-id": this.context["x-thread-id"] || "",
1779
- service_name: this.serviceName,
1780
- logger_name: this.name,
1781
- ...additionalContext
1782
- };
1783
- return pinoLogger.child(contextObj);
1784
- }
1785
- info(msg, obj) {
1786
- this.getContextualLogger(obj).info(msg);
1787
- }
1788
- error(msg, obj) {
1789
- this.getContextualLogger(obj).error(msg);
1790
- }
1791
- warn(msg, obj) {
1792
- this.getContextualLogger(obj).warn(msg);
1793
- }
1794
- debug(msg, obj) {
1795
- this.getContextualLogger(obj).debug(msg);
1796
- }
1797
- /**
1798
- * 更新Logger实例的上下文
1799
- */
1800
- updateContext(context) {
1801
- this.context = {
1802
- ...this.context,
1803
- ...context
1804
- };
1805
- }
1806
- /**
1807
- * 创建一个新的Logger实例,继承当前Logger的上下文
1808
- */
1809
- child(options) {
1810
- return new _Logger({
1811
- name: options.name || this.name,
1812
- serviceName: options.serviceName || this.serviceName,
1813
- context: {
1814
- ...this.context,
1815
- ...options.context
1816
- }
1817
- });
1818
- }
1986
+ app2.get("/api/skills", getSkillList);
1987
+ app2.get(
1988
+ "/api/skills/:id",
1989
+ getSkill
1990
+ );
1991
+ app2.post(
1992
+ "/api/skills",
1993
+ createSkill
1994
+ );
1995
+ app2.put(
1996
+ "/api/skills/:id",
1997
+ updateSkill
1998
+ );
1999
+ app2.delete(
2000
+ "/api/skills/:id",
2001
+ deleteSkill
2002
+ );
2003
+ app2.get(
2004
+ "/api/skills/search/metadata",
2005
+ searchSkillsByMetadata
2006
+ );
2007
+ app2.get(
2008
+ "/api/skills/filter/compatibility",
2009
+ filterSkillsByCompatibility
2010
+ );
2011
+ app2.get(
2012
+ "/api/skills/filter/license",
2013
+ filterSkillsByLicense
2014
+ );
1819
2015
  };
1820
2016
 
1821
2017
  // src/swagger.ts
@@ -2163,13 +2359,33 @@ _AgentTaskConsumer.agent_run_endpoint = "http://localhost:4001/api/runs";
2163
2359
  var AgentTaskConsumer = _AgentTaskConsumer;
2164
2360
 
2165
2361
  // src/index.ts
2362
+ import {
2363
+ registerLoggerLattice,
2364
+ getLoggerLattice,
2365
+ loggerLatticeManager
2366
+ } from "@axiom-lattice/core";
2367
+ import {
2368
+ LoggerType
2369
+ } from "@axiom-lattice/protocols";
2166
2370
  process.on("unhandledRejection", (reason, promise) => {
2167
2371
  console.error("\u672A\u5904\u7406\u7684Promise\u62D2\u7EDD:", reason);
2168
2372
  });
2169
- var logger = new Logger({
2170
- serviceName: "lattice-gateway",
2171
- name: "fastify-server"
2172
- });
2373
+ var DEFAULT_LOGGER_CONFIG = {
2374
+ name: "default",
2375
+ description: "Default logger for lattice-gateway service",
2376
+ type: LoggerType.PINO,
2377
+ serviceName: "lattice/gateway",
2378
+ loggerName: "lattice/gateway"
2379
+ };
2380
+ var loggerLattice = initializeLogger(DEFAULT_LOGGER_CONFIG);
2381
+ var logger = loggerLattice.client;
2382
+ function initializeLogger(config) {
2383
+ if (loggerLatticeManager.hasLattice("default")) {
2384
+ loggerLatticeManager.removeLattice("default");
2385
+ }
2386
+ registerLoggerLattice("default", config);
2387
+ return getLoggerLattice("default");
2388
+ }
2173
2389
  var app = fastify({
2174
2390
  logger: false,
2175
2391
  // 禁用内置日志记录器
@@ -2177,17 +2393,33 @@ var app = fastify({
2177
2393
  // Default 50MB, configurable via BODY_LIMIT env var
2178
2394
  });
2179
2395
  app.addHook("onRequest", (request, reply, done) => {
2396
+ const getHeaderValue = (header) => {
2397
+ if (Array.isArray(header)) {
2398
+ return header[0];
2399
+ }
2400
+ return header;
2401
+ };
2180
2402
  const context = {
2181
- "x-tenant-id": request.headers["x-tenant-id"],
2182
- "x-request-id": request.headers["x-request-id"]
2403
+ "x-tenant-id": getHeaderValue(request.headers["x-tenant-id"]),
2404
+ "x-request-id": getHeaderValue(request.headers["x-request-id"])
2183
2405
  };
2406
+ if (loggerLattice.updateContext) {
2407
+ loggerLattice.updateContext(context);
2408
+ }
2184
2409
  done();
2185
2410
  });
2186
2411
  app.addHook("onResponse", (request, reply, done) => {
2412
+ const getHeaderValue = (header) => {
2413
+ if (Array.isArray(header)) {
2414
+ return header[0];
2415
+ }
2416
+ return header;
2417
+ };
2187
2418
  const context = {
2188
- "x-tenant-id": request.headers["x-tenant-id"],
2189
- "x-request-id": request.headers["x-request-id"]
2419
+ "x-tenant-id": getHeaderValue(request.headers["x-tenant-id"]),
2420
+ "x-request-id": getHeaderValue(request.headers["x-request-id"])
2190
2421
  };
2422
+ loggerLattice.info(`${request.method} ${request.url} - ${reply.statusCode}`);
2191
2423
  done();
2192
2424
  });
2193
2425
  app.register(cors, {
@@ -2205,9 +2437,15 @@ app.register(cors, {
2205
2437
  });
2206
2438
  app.register(sensible);
2207
2439
  app.setErrorHandler((error, request, reply) => {
2440
+ const getHeaderValue = (header) => {
2441
+ if (Array.isArray(header)) {
2442
+ return header[0];
2443
+ }
2444
+ return header;
2445
+ };
2208
2446
  const context = {
2209
- "x-tenant-id": request.headers["x-tenant-id"],
2210
- "x-request-id": request.headers["x-request-id"]
2447
+ "x-tenant-id": getHeaderValue(request.headers["x-tenant-id"]),
2448
+ "x-request-id": getHeaderValue(request.headers["x-request-id"])
2211
2449
  };
2212
2450
  logger.error(
2213
2451
  `\u8BF7\u6C42\u9519\u8BEF: ${request.method} ${request.url} error:${error.message}`,
@@ -2223,9 +2461,19 @@ app.setErrorHandler((error, request, reply) => {
2223
2461
  error: error.message || "\u670D\u52A1\u5668\u5185\u90E8\u9519\u8BEF"
2224
2462
  });
2225
2463
  });
2226
- app.decorate("logger", logger);
2227
2464
  var start = async (config) => {
2228
2465
  try {
2466
+ if (config?.loggerConfig) {
2467
+ const loggerConfig = {
2468
+ ...DEFAULT_LOGGER_CONFIG,
2469
+ ...config.loggerConfig,
2470
+ // Merge file config if provided
2471
+ file: config.loggerConfig.file || DEFAULT_LOGGER_CONFIG.file
2472
+ };
2473
+ loggerLattice = initializeLogger(loggerConfig);
2474
+ logger = loggerLattice.client;
2475
+ }
2476
+ app.decorate("loggerLattice", loggerLattice);
2229
2477
  const target_port = config?.port || Number(process.env.PORT) || 4001;
2230
2478
  await app.listen({ port: target_port, host: "0.0.0.0" });
2231
2479
  logger.info(`Lattice Gateway is running on port: ${target_port}`);