openclaw-observability 2026.3.23 → 2026.3.24-1

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 (44) hide show
  1. package/dist/config.d.ts +9 -0
  2. package/dist/config.d.ts.map +1 -1
  3. package/dist/config.js +9 -0
  4. package/dist/config.js.map +1 -1
  5. package/dist/index.d.ts +5 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +320 -5
  8. package/dist/index.js.map +1 -1
  9. package/dist/security/chain-detector.d.ts +0 -9
  10. package/dist/security/chain-detector.d.ts.map +1 -1
  11. package/dist/security/chain-detector.js +7 -25
  12. package/dist/security/chain-detector.js.map +1 -1
  13. package/dist/security/rules.d.ts.map +1 -1
  14. package/dist/security/rules.js +30 -24
  15. package/dist/security/rules.js.map +1 -1
  16. package/dist/storage/duckdb-local-writer.d.ts +5 -1
  17. package/dist/storage/duckdb-local-writer.d.ts.map +1 -1
  18. package/dist/storage/duckdb-local-writer.js +443 -1
  19. package/dist/storage/duckdb-local-writer.js.map +1 -1
  20. package/dist/storage/mysql-writer.d.ts +3 -1
  21. package/dist/storage/mysql-writer.d.ts.map +1 -1
  22. package/dist/storage/mysql-writer.js +175 -0
  23. package/dist/storage/mysql-writer.js.map +1 -1
  24. package/dist/storage/schema.d.ts.map +1 -1
  25. package/dist/storage/schema.js +144 -0
  26. package/dist/storage/schema.js.map +1 -1
  27. package/dist/storage/structured-model.d.ts +68 -0
  28. package/dist/storage/structured-model.d.ts.map +1 -0
  29. package/dist/storage/structured-model.js +313 -0
  30. package/dist/storage/structured-model.js.map +1 -0
  31. package/dist/storage/writer.d.ts +23 -0
  32. package/dist/storage/writer.d.ts.map +1 -1
  33. package/dist/web/api.d.ts +66 -0
  34. package/dist/web/api.d.ts.map +1 -1
  35. package/dist/web/api.js +269 -0
  36. package/dist/web/api.js.map +1 -1
  37. package/dist/web/routes.d.ts +6 -2
  38. package/dist/web/routes.d.ts.map +1 -1
  39. package/dist/web/routes.js +402 -9
  40. package/dist/web/routes.js.map +1 -1
  41. package/dist/web/ui.js +1718 -216
  42. package/dist/web/ui.js.map +1 -1
  43. package/openclaw.plugin.json +36 -1
  44. package/package.json +5 -2
package/dist/config.d.ts CHANGED
@@ -58,6 +58,14 @@ export interface UiConfig {
58
58
  /** Optional access token: when set, requests must pass ?token=... or Authorization: Bearer ... */
59
59
  accessToken?: string;
60
60
  }
61
+ export interface MetricsConfig {
62
+ /** Enable OTLP push ingest endpoint */
63
+ enabled: boolean;
64
+ /** OTLP base path mounted on plugin route (the receiver listens on ${otlpPath}/v1/metrics) */
65
+ otlpPath: string;
66
+ /** Max payload size for OTLP metrics requests */
67
+ maxPayloadBytes: number;
68
+ }
61
69
  /** Full plugin config */
62
70
  export interface AuditPluginConfig {
63
71
  /** Storage mode: local (embedded, zero config) | remote (external MySQL) */
@@ -68,6 +76,7 @@ export interface AuditPluginConfig {
68
76
  redaction: RedactionConfig;
69
77
  security: SecurityPluginConfig;
70
78
  ui?: UiConfig;
79
+ metrics: MetricsConfig;
71
80
  }
72
81
  /** Default DuckDB path — use a 'data' subdirectory to avoid triggering
73
82
  * OpenClaw's hot-reload file watcher on the top-level ~/.openclaw/ dir */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,8BAA8B;AAC9B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,0BAA0B;AAC1B,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oBAAoB;AACpB,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,uBAAuB;AACvB,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,gCAAgC;AAChC,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,KAAK,CAAC;QACtB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC,CAAC;IACH,2CAA2C;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,KAAK,EAAE;QACL,aAAa,EAAE,OAAO,CAAC;QACvB,WAAW,EAAE,OAAO,CAAC;QACrB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,eAAe,EAAE,OAAO,CAAC;QACzB,WAAW,EAAE,OAAO,CAAC;QACrB,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,sDAAsD;IACtD,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,sCAAsC;AACtC,MAAM,WAAW,QAAQ;IACvB,kGAAkG;IAClG,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,yBAAyB;AACzB,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,EAAE,CAAC,EAAE,QAAQ,CAAC;CACf;AAED;2EAC2E;AAC3E,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AAEF,qBAAqB;AACrB,eAAO,MAAM,cAAc,EAAE,iBAiD5B,CAAC;AAeF,wBAAgB,aAAa,CAC3B,UAAU,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,SAAS,GACjD,iBAAiB,CAuCnB"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,8BAA8B;AAC9B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,0BAA0B;AAC1B,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oBAAoB;AACpB,MAAM,WAAW,YAAY;IAC3B,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,uBAAuB;AACvB,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,gCAAgC;AAChC,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,KAAK,CAAC;QACtB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC,CAAC;IACH,2CAA2C;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,KAAK,EAAE;QACL,aAAa,EAAE,OAAO,CAAC;QACvB,WAAW,EAAE,OAAO,CAAC;QACrB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,eAAe,EAAE,OAAO,CAAC;QACzB,WAAW,EAAE,OAAO,CAAC;QACrB,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,sDAAsD;IACtD,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,sCAAsC;AACtC,MAAM,WAAW,QAAQ;IACvB,kGAAkG;IAClG,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,8FAA8F;IAC9F,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,yBAAyB;AACzB,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,SAAS,EAAE,eAAe,CAAC;IAC3B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,EAAE,CAAC,EAAE,QAAQ,CAAC;IACd,OAAO,EAAE,aAAa,CAAC;CACxB;AAED;2EAC2E;AAC3E,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AAEF,qBAAqB;AACrB,eAAO,MAAM,cAAc,EAAE,iBAsD5B,CAAC;AAeF,wBAAgB,aAAa,CAC3B,UAAU,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,SAAS,GACjD,iBAAiB,CA2CnB"}
package/dist/config.js CHANGED
@@ -93,6 +93,11 @@ exports.DEFAULT_CONFIG = {
93
93
  domainWhitelist: [],
94
94
  },
95
95
  ui: {},
96
+ metrics: {
97
+ enabled: true,
98
+ otlpPath: '/plugins/observability/api/otel',
99
+ maxPayloadBytes: 2 * 1024 * 1024,
100
+ },
96
101
  };
97
102
  /**
98
103
  * Smart mode inference:
@@ -145,6 +150,10 @@ function resolveConfig(userConfig) {
145
150
  ...exports.DEFAULT_CONFIG.ui,
146
151
  ...userConfig.ui,
147
152
  },
153
+ metrics: {
154
+ ...exports.DEFAULT_CONFIG.metrics,
155
+ ...userConfig.metrics,
156
+ },
148
157
  };
149
158
  }
150
159
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuJH,sCAyCC;AA9LD,2CAA6B;AAC7B,uCAAyB;AA6EzB;2EAC2E;AAC9D,QAAA,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAC1C,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,sBAAsB,CAC1D,CAAC;AAEF,qBAAqB;AACR,QAAA,cAAc,GAAsB;IAC/C,IAAI,EAAE,OAAO,EAAG,qCAAqC;IACrD,KAAK,EAAE;QACL,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,wBAAwB;KACnC;IACD,MAAM,EAAE;QACN,IAAI,EAAE,2BAAmB;KAC1B;IACD,MAAM,EAAE;QACN,SAAS,EAAE,EAAE;QACb,eAAe,EAAE,IAAI;KACtB;IACD,SAAS,EAAE;QACT,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE;YACR,SAAS;YACT,gBAAgB;YAChB,UAAU;YACV,QAAQ;YACR,cAAc;YACd,YAAY;YACZ,eAAe;YACf,cAAc;YACd,eAAe;YACf,YAAY;YACZ,YAAY;YACZ,eAAe;YACf,aAAa;YACb,YAAY;SACb;KACF;IACD,QAAQ,EAAE;QACR,gBAAgB,EAAE,EAAE;QACpB,OAAO,EAAE,IAAI;QACb,KAAK,EAAE;YACL,aAAa,EAAE,IAAI;YACnB,WAAW,EAAE,IAAI;YACjB,gBAAgB,EAAE,KAAK;YACvB,eAAe,EAAE,KAAK;YACtB,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,KAAK;SACtB;QACD,eAAe,EAAE,EAAE;KACpB;IACD,EAAE,EAAE,EAAE;CACP,CAAC;AAEF;;;;;GAKG;AACH,SAAS,SAAS,CAAC,UAAsC;IACvD,IAAI,UAAU,CAAC,IAAI;QAAE,OAAO,UAAU,CAAC,IAAI,CAAC;IAC5C,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;IAC3B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACzE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAgB,aAAa,CAC3B,UAAkD;IAElD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,GAAG,sBAAc,EAAE,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC;QAC3B,KAAK,EAAE;YACL,GAAG,sBAAc,CAAC,KAAK;YACvB,GAAG,UAAU,CAAC,KAAK;SACpB;QACD,MAAM,EAAE;YACN,GAAG,sBAAc,CAAC,MAAM;YACxB,GAAG,UAAU,CAAC,MAAM;SACrB;QACD,MAAM,EAAE;YACN,GAAG,sBAAc,CAAC,MAAM;YACxB,GAAG,UAAU,CAAC,MAAM;SACrB;QACD,SAAS,EAAE;YACT,GAAG,sBAAc,CAAC,SAAS;YAC3B,GAAG,UAAU,CAAC,SAAS;YACvB,QAAQ,EAAE,UAAU,CAAC,SAAS,EAAE,QAAQ,IAAI,sBAAc,CAAC,SAAS,CAAC,QAAQ;SAC9E;QACD,QAAQ,EAAE;YACR,GAAG,sBAAc,CAAC,QAAQ;YAC1B,GAAG,UAAU,CAAC,QAAQ;YACtB,KAAK,EAAE;gBACL,GAAG,sBAAc,CAAC,QAAQ,CAAC,KAAK;gBAChC,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC;aAChC;YACD,gBAAgB,EAAE,UAAU,CAAC,QAAQ,EAAE,gBAAgB,IAAI,sBAAc,CAAC,QAAQ,CAAC,gBAAgB;YACnG,eAAe,EAAE,UAAU,CAAC,QAAQ,EAAE,eAAe,IAAI,sBAAc,CAAC,QAAQ,CAAC,eAAe;SACjG;QACD,EAAE,EAAE;YACF,GAAG,sBAAc,CAAC,EAAE;YACpB,GAAG,UAAU,CAAC,EAAE;SACjB;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsKH,sCA6CC;AAjND,2CAA6B;AAC7B,uCAAyB;AAuFzB;2EAC2E;AAC9D,QAAA,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAC1C,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,sBAAsB,CAC1D,CAAC;AAEF,qBAAqB;AACR,QAAA,cAAc,GAAsB;IAC/C,IAAI,EAAE,OAAO,EAAG,qCAAqC;IACrD,KAAK,EAAE;QACL,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,wBAAwB;KACnC;IACD,MAAM,EAAE;QACN,IAAI,EAAE,2BAAmB;KAC1B;IACD,MAAM,EAAE;QACN,SAAS,EAAE,EAAE;QACb,eAAe,EAAE,IAAI;KACtB;IACD,SAAS,EAAE;QACT,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE;YACR,SAAS;YACT,gBAAgB;YAChB,UAAU;YACV,QAAQ;YACR,cAAc;YACd,YAAY;YACZ,eAAe;YACf,cAAc;YACd,eAAe;YACf,YAAY;YACZ,YAAY;YACZ,eAAe;YACf,aAAa;YACb,YAAY;SACb;KACF;IACD,QAAQ,EAAE;QACR,gBAAgB,EAAE,EAAE;QACpB,OAAO,EAAE,IAAI;QACb,KAAK,EAAE;YACL,aAAa,EAAE,IAAI;YACnB,WAAW,EAAE,IAAI;YACjB,gBAAgB,EAAE,KAAK;YACvB,eAAe,EAAE,KAAK;YACtB,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,KAAK;SACtB;QACD,eAAe,EAAE,EAAE;KACpB;IACD,EAAE,EAAE,EAAE;IACN,OAAO,EAAE;QACP,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE,iCAAiC;QAC3C,eAAe,EAAE,CAAC,GAAG,IAAI,GAAG,IAAI;KACjC;CACF,CAAC;AAEF;;;;;GAKG;AACH,SAAS,SAAS,CAAC,UAAsC;IACvD,IAAI,UAAU,CAAC,IAAI;QAAE,OAAO,UAAU,CAAC,IAAI,CAAC;IAC5C,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC;IAC3B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IACzE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAgB,aAAa,CAC3B,UAAkD;IAElD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,EAAE,GAAG,sBAAc,EAAE,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,UAAU,CAAC;QAC3B,KAAK,EAAE;YACL,GAAG,sBAAc,CAAC,KAAK;YACvB,GAAG,UAAU,CAAC,KAAK;SACpB;QACD,MAAM,EAAE;YACN,GAAG,sBAAc,CAAC,MAAM;YACxB,GAAG,UAAU,CAAC,MAAM;SACrB;QACD,MAAM,EAAE;YACN,GAAG,sBAAc,CAAC,MAAM;YACxB,GAAG,UAAU,CAAC,MAAM;SACrB;QACD,SAAS,EAAE;YACT,GAAG,sBAAc,CAAC,SAAS;YAC3B,GAAG,UAAU,CAAC,SAAS;YACvB,QAAQ,EAAE,UAAU,CAAC,SAAS,EAAE,QAAQ,IAAI,sBAAc,CAAC,SAAS,CAAC,QAAQ;SAC9E;QACD,QAAQ,EAAE;YACR,GAAG,sBAAc,CAAC,QAAQ;YAC1B,GAAG,UAAU,CAAC,QAAQ;YACtB,KAAK,EAAE;gBACL,GAAG,sBAAc,CAAC,QAAQ,CAAC,KAAK;gBAChC,GAAG,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC;aAChC;YACD,gBAAgB,EAAE,UAAU,CAAC,QAAQ,EAAE,gBAAgB,IAAI,sBAAc,CAAC,QAAQ,CAAC,gBAAgB;YACnG,eAAe,EAAE,UAAU,CAAC,QAAQ,EAAE,eAAe,IAAI,sBAAc,CAAC,QAAQ,CAAC,eAAe;SACjG;QACD,EAAE,EAAE;YACF,GAAG,sBAAc,CAAC,EAAE;YACpB,GAAG,UAAU,CAAC,EAAE;SACjB;QACD,OAAO,EAAE;YACP,GAAG,sBAAc,CAAC,OAAO;YACzB,GAAG,UAAU,CAAC,OAAO;SACtB;KACF,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -27,6 +27,11 @@ interface PluginAPI {
27
27
  match?: 'exact' | 'prefix';
28
28
  replaceExisting?: boolean;
29
29
  }) => void;
30
+ registerGatewayMethod?: (method: string, handler: (ctx: {
31
+ params?: unknown;
32
+ respond: (ok: boolean, payload: unknown) => void;
33
+ [key: string]: unknown;
34
+ }) => void | Promise<void>) => void;
30
35
  runtime?: {
31
36
  events?: {
32
37
  onAgentEvent?: (listener: (evt: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,iBAAiB,EAAiB,MAAM,UAAU,CAAC;AAmB5D,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC1C,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;IACjE,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE;QAC3B,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,WAAW,EAAE,eAAe,EAAE,GAAG,EAAE,OAAO,WAAW,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;QACzI,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;QAC3B,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;QAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE;YACP,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE;gBAC9B,KAAK,EAAE,MAAM,CAAC;gBACd,MAAM,EAAE,MAAM,CAAC;gBACf,EAAE,EAAE,MAAM,CAAC;gBACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;aACrB,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;SACpC,CAAC;KACH,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAu5BD,iBAAS,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG;IAAE,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAy7CrE;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,iBAAiB,EAAiB,MAAM,UAAU,CAAC;AAiC5D,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC1C,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;IACjE,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE;QAC3B,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,CAAC,GAAG,EAAE,OAAO,WAAW,EAAE,eAAe,EAAE,GAAG,EAAE,OAAO,WAAW,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC;QACzI,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;QAC3B,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;QAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX,qBAAqB,CAAC,EAAE,CACtB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,CAAC,GAAG,EAAE;QACb,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;QACjD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KACvB,IAAI,CAAC;IACV,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE;YACP,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,EAAE;gBAC9B,KAAK,EAAE,MAAM,CAAC;gBACd,MAAM,EAAE,MAAM,CAAC;gBACf,EAAE,EAAE,MAAM,CAAC;gBACX,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;aACrB,KAAK,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;SACpC,CAAC;KACH,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAu5BD,iBAAS,QAAQ,CAAC,GAAG,EAAE,SAAS,GAAG;IAAE,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CA2vDrE;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC;AACpB,eAAe,QAAQ,CAAC"}
package/dist/index.js CHANGED
@@ -55,6 +55,7 @@ const mysql_writer_1 = require("./storage/mysql-writer");
55
55
  const duckdb_local_writer_1 = require("./storage/duckdb-local-writer");
56
56
  const buffer_1 = require("./storage/buffer");
57
57
  const routes_1 = require("./web/routes");
58
+ const api_1 = require("./web/api");
58
59
  const scanner_1 = require("./security/scanner");
59
60
  const fs = __importStar(require("node:fs"));
60
61
  const path = __importStar(require("node:path"));
@@ -907,7 +908,8 @@ function activate(api) {
907
908
  'Please configure via Dashboard (Settings → Plugins → openclaw-observability Config) then restart.');
908
909
  }
909
910
  }
910
- // Observability UI auth: read gateway.auth.token from same config file as gateway; if missing or empty, no auth (allow all)
911
+ // UI shell stays directly open; legacy HTTP APIs still accept gateway token
912
+ // for backward compatibility. WS data access is authenticated at gateway connect.
911
913
  const openclawConfigPath = process.env.OPENCLAW_CONFIG_PATH ?? path.join(stateDir, 'openclaw.json');
912
914
  let observabilityToken;
913
915
  try {
@@ -919,7 +921,6 @@ function activate(api) {
919
921
  t = parsed?.gateway?.auth?.token;
920
922
  }
921
923
  catch {
922
- // Config may be JSON5 (comments, unescaped newlines in strings); extract token with regex
923
924
  const m = raw.match(/"gateway"\s*:\s*\{[\s\S]*?"auth"\s*:\s*\{[\s\S]*?"token"\s*:\s*"((?:[^"\\]|\\.)*)"/);
924
925
  t = m?.[1]?.replace(/\\(.)/g, '$1');
925
926
  }
@@ -931,10 +932,10 @@ function activate(api) {
931
932
  console.warn('[openclaw-observability] Failed to read gateway token from config:', e.message);
932
933
  }
933
934
  if (observabilityToken) {
934
- console.log('[openclaw-observability] Observability UI auth: token required (from ' + openclawConfigPath + ')');
935
+ console.log('[openclaw-observability] Observability HTTP API auth: token compatibility enabled (from ' + openclawConfigPath + ')');
935
936
  }
936
937
  else {
937
- console.log('[openclaw-observability] Observability UI auth: no token, allow all');
938
+ console.log('[openclaw-observability] Observability HTTP API auth: no token configured');
938
939
  }
939
940
  // Always register HTTP routes on the current api (the latest api serves HTTP)
940
941
  if (typeof api.registerHttpRoute === 'function') {
@@ -949,11 +950,325 @@ function activate(api) {
949
950
  `customRegexRules=${next.customRegexRules.length}`);
950
951
  return next;
951
952
  },
952
- });
953
+ }, config.metrics);
953
954
  }
954
955
  else {
955
956
  console.warn('[openclaw-observability] registerHttpRoute not available — observability UI disabled');
956
957
  }
958
+ if (typeof api.registerGatewayMethod === 'function') {
959
+ const toInt = (value, defaultValue) => {
960
+ const n = Number(value);
961
+ if (!Number.isFinite(n))
962
+ return defaultValue;
963
+ const i = Math.floor(n);
964
+ return i > 0 ? i : defaultValue;
965
+ };
966
+ const toStringOrUndefined = (value) => {
967
+ if (typeof value !== 'string')
968
+ return undefined;
969
+ const trimmed = value.trim();
970
+ return trimmed.length > 0 ? trimmed : undefined;
971
+ };
972
+ const toRecord = (value) => {
973
+ if (value && typeof value === 'object' && !Array.isArray(value)) {
974
+ return value;
975
+ }
976
+ return {};
977
+ };
978
+ const toBool = (value, defaultValue = false) => {
979
+ if (typeof value === 'boolean')
980
+ return value;
981
+ if (typeof value === 'number')
982
+ return value !== 0;
983
+ if (typeof value === 'string') {
984
+ const v = value.trim().toLowerCase();
985
+ if (!v)
986
+ return defaultValue;
987
+ if (v === '1' || v === 'true' || v === 'yes' || v === 'y' || v === 'on')
988
+ return true;
989
+ if (v === '0' || v === 'false' || v === 'no' || v === 'n' || v === 'off')
990
+ return false;
991
+ }
992
+ return defaultValue;
993
+ };
994
+ const resolveLogPath = (sourceRaw) => {
995
+ const source = toStringOrUndefined(sourceRaw) || 'gateway';
996
+ const logsDir = path.join(os.homedir(), '.openclaw', 'logs');
997
+ if (source === 'gateway') {
998
+ return { source, path: path.join(logsDir, 'gateway.log') };
999
+ }
1000
+ if (source === 'gateway.err' || source === 'gateway_error') {
1001
+ return { source: 'gateway.err', path: path.join(logsDir, 'gateway.err.log') };
1002
+ }
1003
+ if (source === 'runtime') {
1004
+ const runtimeDir = path.join(os.tmpdir(), 'openclaw');
1005
+ try {
1006
+ const files = fs
1007
+ .readdirSync(runtimeDir)
1008
+ .filter((f) => /^openclaw-\d{4}-\d{2}-\d{2}\.log$/.test(f))
1009
+ .map((f) => ({
1010
+ file: f,
1011
+ mtime: fs.statSync(path.join(runtimeDir, f)).mtimeMs,
1012
+ }))
1013
+ .sort((a, b) => b.mtime - a.mtime);
1014
+ if (files.length > 0) {
1015
+ return { source, path: path.join(runtimeDir, files[0].file) };
1016
+ }
1017
+ }
1018
+ catch {
1019
+ return { source, path: null };
1020
+ }
1021
+ return { source, path: null };
1022
+ }
1023
+ return { source, path: null };
1024
+ };
1025
+ const registerGateway = (method, handler) => {
1026
+ try {
1027
+ api.registerGatewayMethod(method, async ({ params, respond }) => {
1028
+ try {
1029
+ await writer.ensureReady();
1030
+ const pool = writer.getPool();
1031
+ if (!pool) {
1032
+ respond(false, { error: 'Database not ready — will retry automatically' });
1033
+ return;
1034
+ }
1035
+ await handler({ params, respond });
1036
+ }
1037
+ catch (e) {
1038
+ respond(false, {
1039
+ error: e?.message || `Failed to call ${method}`,
1040
+ });
1041
+ }
1042
+ });
1043
+ }
1044
+ catch (e) {
1045
+ console.warn(`[openclaw-observability] Failed to register gateway method ${method}:`, e.message);
1046
+ }
1047
+ };
1048
+ registerGateway('observability.stats', async ({ respond }) => {
1049
+ const pool = writer.getPool();
1050
+ const stats = await (0, api_1.getStats)(pool);
1051
+ respond(true, stats);
1052
+ });
1053
+ registerGateway('observability.sessions', async ({ params, respond }) => {
1054
+ const pool = writer.getPool();
1055
+ const p = toRecord(params);
1056
+ const result = await (0, api_1.getSessions)(pool, {
1057
+ page: toInt(p.page, 1),
1058
+ limit: toInt(p.limit, 20),
1059
+ userId: toStringOrUndefined(p.user_id),
1060
+ model: toStringOrUndefined(p.model),
1061
+ sessionId: toStringOrUndefined(p.sessionId),
1062
+ search: toStringOrUndefined(p.search),
1063
+ timeFrom: toStringOrUndefined(p.timeFrom),
1064
+ timeTo: toStringOrUndefined(p.timeTo),
1065
+ });
1066
+ respond(true, result);
1067
+ });
1068
+ registerGateway('observability.session.actions', async ({ params, respond }) => {
1069
+ const pool = writer.getPool();
1070
+ const p = toRecord(params);
1071
+ const sessionId = toStringOrUndefined(p.sessionId);
1072
+ if (!sessionId) {
1073
+ respond(false, { error: 'sessionId is required' });
1074
+ return;
1075
+ }
1076
+ const fields = toStringOrUndefined(p.fields);
1077
+ const limit = p.limit == null ? undefined : toInt(p.limit, 1000);
1078
+ const actions = await (0, api_1.getSessionActions)(pool, sessionId, { fields, limit });
1079
+ respond(true, { actions });
1080
+ });
1081
+ registerGateway('observability.session.tree', async ({ params, respond }) => {
1082
+ const pool = writer.getPool();
1083
+ const p = toRecord(params);
1084
+ const sessionId = toStringOrUndefined(p.sessionId);
1085
+ if (!sessionId) {
1086
+ respond(false, { error: 'sessionId is required' });
1087
+ return;
1088
+ }
1089
+ const tree = await (0, api_1.getTraceObservationTree)(pool, sessionId);
1090
+ respond(true, tree);
1091
+ });
1092
+ registerGateway('observability.session.graph', async ({ params, respond }) => {
1093
+ const pool = writer.getPool();
1094
+ const p = toRecord(params);
1095
+ const sessionId = toStringOrUndefined(p.sessionId);
1096
+ if (!sessionId) {
1097
+ respond(false, { error: 'sessionId is required' });
1098
+ return;
1099
+ }
1100
+ const graph = await (0, api_1.getTraceObservationTree)(pool, sessionId);
1101
+ respond(true, graph);
1102
+ });
1103
+ registerGateway('observability.actions', async ({ params, respond }) => {
1104
+ const pool = writer.getPool();
1105
+ const p = toRecord(params);
1106
+ const result = await (0, api_1.getActions)(pool, {
1107
+ page: toInt(p.page, 1),
1108
+ limit: toInt(p.limit, 50),
1109
+ actionType: toStringOrUndefined(p.action_type),
1110
+ sessionId: toStringOrUndefined(p.session_id),
1111
+ });
1112
+ respond(true, result);
1113
+ });
1114
+ registerGateway('observability.alerts.stats', async ({ respond }) => {
1115
+ const pool = writer.getPool();
1116
+ const stats = await (0, api_1.getAlertStats)(pool);
1117
+ respond(true, stats);
1118
+ });
1119
+ registerGateway('observability.alerts', async ({ params, respond }) => {
1120
+ const pool = writer.getPool();
1121
+ const p = toRecord(params);
1122
+ const result = await (0, api_1.getAlerts)(pool, {
1123
+ page: toInt(p.page, 1),
1124
+ limit: toInt(p.limit, 20),
1125
+ severity: toStringOrUndefined(p.severity),
1126
+ category: toStringOrUndefined(p.category),
1127
+ status: toStringOrUndefined(p.status),
1128
+ sessionId: toStringOrUndefined(p.session_id),
1129
+ ruleId: toStringOrUndefined(p.rule_id),
1130
+ search: toStringOrUndefined(p.search),
1131
+ timeFrom: toStringOrUndefined(p.timeFrom),
1132
+ timeTo: toStringOrUndefined(p.timeTo),
1133
+ });
1134
+ respond(true, result);
1135
+ });
1136
+ registerGateway('observability.alerts.updateStatus', async ({ params, respond }) => {
1137
+ const pool = writer.getPool();
1138
+ const p = toRecord(params);
1139
+ const alertId = toStringOrUndefined(p.alertId);
1140
+ const status = toStringOrUndefined(p.status);
1141
+ const resolvedBy = toStringOrUndefined(p.resolvedBy);
1142
+ if (!alertId || !status) {
1143
+ respond(false, { error: 'alertId and status are required' });
1144
+ return;
1145
+ }
1146
+ const ok = await (0, api_1.updateAlertStatus)(pool, alertId, status, resolvedBy);
1147
+ respond(true, { success: ok });
1148
+ });
1149
+ registerGateway('observability.session.alerts', async ({ params, respond }) => {
1150
+ const pool = writer.getPool();
1151
+ const p = toRecord(params);
1152
+ const sessionId = toStringOrUndefined(p.sessionId);
1153
+ if (!sessionId) {
1154
+ respond(false, { error: 'sessionId is required' });
1155
+ return;
1156
+ }
1157
+ const alerts = await (0, api_1.getSessionAlerts)(pool, sessionId);
1158
+ respond(true, { alerts });
1159
+ });
1160
+ registerGateway('observability.analytics', async ({ params, respond }) => {
1161
+ const pool = writer.getPool();
1162
+ const p = toRecord(params);
1163
+ const result = await (0, api_1.getAnalytics)(pool, {
1164
+ timeFrom: toStringOrUndefined(p.timeFrom),
1165
+ timeTo: toStringOrUndefined(p.timeTo),
1166
+ });
1167
+ respond(true, result);
1168
+ });
1169
+ registerGateway('observability.security.config.get', async ({ respond }) => {
1170
+ respond(true, { config: securityScanner.getConfig() });
1171
+ });
1172
+ registerGateway('observability.security.config.update', async ({ params, respond }) => {
1173
+ const p = toRecord(params);
1174
+ const next = securityScanner.updateConfig(p);
1175
+ persistSecurityConfig(next);
1176
+ respond(true, { config: next });
1177
+ });
1178
+ registerGateway('observability.metrics.overview', async ({ params, respond }) => {
1179
+ const pool = writer.getPool();
1180
+ if (!(config.metrics.enabled && typeof writer.writeMetricSamples === 'function')) {
1181
+ respond(true, {
1182
+ enabled: false,
1183
+ otlpPath: config.metrics.otlpPath,
1184
+ totalMetrics: 0,
1185
+ totalSamples: 0,
1186
+ items: [],
1187
+ lastIngestAt: null,
1188
+ lastError: 'metrics.disabled',
1189
+ });
1190
+ return;
1191
+ }
1192
+ const p = toRecord(params);
1193
+ const minutes = toInt(p.minutes, 60);
1194
+ const limit = toInt(p.limit, 100);
1195
+ const overview = await (0, api_1.getMetricsOverview)(pool, { minutes, limit });
1196
+ respond(true, {
1197
+ enabled: true,
1198
+ otlpPath: config.metrics.otlpPath,
1199
+ otlpMetricsEndpoint: `${config.metrics.otlpPath}/v1/metrics`,
1200
+ ...overview,
1201
+ });
1202
+ });
1203
+ registerGateway('observability.metrics.series', async ({ params, respond }) => {
1204
+ const pool = writer.getPool();
1205
+ const p = toRecord(params);
1206
+ const metricName = toStringOrUndefined(p.metricName);
1207
+ if (!metricName) {
1208
+ respond(false, { error: 'metricName is required' });
1209
+ return;
1210
+ }
1211
+ const minutes = toInt(p.minutes, 60);
1212
+ const stepSec = toInt(p.stepSec, 30);
1213
+ const result = await (0, api_1.getMetricSeries)(pool, { metricName, minutes, stepSec });
1214
+ respond(true, result);
1215
+ });
1216
+ registerGateway('observability.logs', async ({ params, respond }) => {
1217
+ const p = toRecord(params);
1218
+ const { source, path: logPath } = resolveLogPath(p.source);
1219
+ if (!logPath) {
1220
+ respond(false, { error: `unsupported log source: ${String(p.source || '')}` });
1221
+ return;
1222
+ }
1223
+ if (!fs.existsSync(logPath)) {
1224
+ respond(false, { error: `log file not found: ${logPath}` });
1225
+ return;
1226
+ }
1227
+ const limit = Math.min(toInt(p.limit, 200), 2000);
1228
+ const search = toStringOrUndefined(p.search);
1229
+ const sessionId = toStringOrUndefined(p.sessionId);
1230
+ const caseSensitive = toBool(p.caseSensitive, false);
1231
+ const beforeLine = Math.max(0, Number(p.beforeLine || 0));
1232
+ const hasBefore = Number.isFinite(beforeLine) && beforeLine > 0;
1233
+ const raw = fs.readFileSync(logPath, 'utf8');
1234
+ const lines = raw.split(/\r?\n/);
1235
+ const endExclusive = hasBefore ? Math.min(beforeLine, lines.length) : lines.length;
1236
+ const filtered = [];
1237
+ const needleRaw = (search || sessionId || '').trim();
1238
+ const needle = caseSensitive ? needleRaw : needleRaw.toLowerCase();
1239
+ for (let i = 0; i < endExclusive; i++) {
1240
+ const lineText = lines[i] || '';
1241
+ if (!lineText)
1242
+ continue;
1243
+ if (needle) {
1244
+ const hay = caseSensitive ? lineText : lineText.toLowerCase();
1245
+ if (!hay.includes(needle))
1246
+ continue;
1247
+ }
1248
+ const tsMatch = lineText.match(/^(\d{4}-\d{2}-\d{2}T[^\s]+)/);
1249
+ filtered.push({
1250
+ line: i + 1,
1251
+ text: lineText,
1252
+ timestamp: tsMatch ? tsMatch[1] : null,
1253
+ });
1254
+ }
1255
+ const items = filtered.slice(Math.max(0, filtered.length - limit));
1256
+ const nextBeforeLine = items.length > 0 ? items[0].line : 0;
1257
+ respond(true, {
1258
+ source,
1259
+ path: logPath,
1260
+ totalLines: lines.length,
1261
+ totalMatched: filtered.length,
1262
+ returned: items.length,
1263
+ nextBeforeLine,
1264
+ items,
1265
+ });
1266
+ });
1267
+ console.log('[openclaw-observability] Gateway methods registered: observability.*');
1268
+ }
1269
+ else {
1270
+ console.warn('[openclaw-observability] registerGatewayMethod not available — RPC observability.* disabled');
1271
+ }
957
1272
  // ====================== Helper functions ======================
958
1273
  /** Record action, update session stats, and run security scan */
959
1274
  function recordAction(action, tokens = 0) {