@senpi/runtime 3.0.148 → 3.0.150

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 (88) hide show
  1. package/dist/cli/guide-commands.d.ts.map +1 -1
  2. package/dist/cli/guide-commands.js +55 -0
  3. package/dist/cli/guide-commands.js.map +1 -1
  4. package/dist/cli/quant-command.d.ts +128 -0
  5. package/dist/cli/quant-command.d.ts.map +1 -0
  6. package/dist/cli/quant-command.js +345 -0
  7. package/dist/cli/quant-command.js.map +1 -0
  8. package/dist/cli/senpi-commands.d.ts +11 -0
  9. package/dist/cli/senpi-commands.d.ts.map +1 -1
  10. package/dist/cli/senpi-commands.js +49 -4
  11. package/dist/cli/senpi-commands.js.map +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +40 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/quant/engine/quantdesk/__init__.py +19 -0
  16. package/dist/quant/engine/quantdesk/__main__.py +281 -0
  17. package/dist/quant/engine/quantdesk/_version.py +24 -0
  18. package/dist/quant/engine/quantdesk/benchmark.py +90 -0
  19. package/dist/quant/engine/quantdesk/book.py +197 -0
  20. package/dist/quant/engine/quantdesk/deep.py +197 -0
  21. package/dist/quant/engine/quantdesk/desk.py +878 -0
  22. package/dist/quant/engine/quantdesk/dsl.py +224 -0
  23. package/dist/quant/engine/quantdesk/followups.py +117 -0
  24. package/dist/quant/engine/quantdesk/hl_api.py +473 -0
  25. package/dist/quant/engine/quantdesk/market.py +290 -0
  26. package/dist/quant/engine/quantdesk/mcp_client.py +158 -0
  27. package/dist/quant/engine/quantdesk/metrics.py +409 -0
  28. package/dist/quant/engine/quantdesk/opportunities.py +88 -0
  29. package/dist/quant/engine/quantdesk/render.py +787 -0
  30. package/dist/quant/engine/quantdesk/roundtrips.py +124 -0
  31. package/dist/quant/engine/quantdesk/score.py +817 -0
  32. package/dist/quant/engine/quantdesk/senpi_history.py +160 -0
  33. package/dist/quant/engine/quantdesk/smart_money.py +354 -0
  34. package/dist/quant/engine/quantdesk/strategy_read.py +292 -0
  35. package/dist/quant/engine/quantdesk/taxonomy.py +55 -0
  36. package/dist/quant/engine/quantdesk/timing.py +164 -0
  37. package/dist/quant/engine/quantdesk/voice.py +42 -0
  38. package/dist/quant/engine-runner.d.ts +133 -0
  39. package/dist/quant/engine-runner.d.ts.map +1 -0
  40. package/dist/quant/engine-runner.js +306 -0
  41. package/dist/quant/engine-runner.js.map +1 -0
  42. package/dist/quant/job.d.ts +125 -0
  43. package/dist/quant/job.d.ts.map +1 -0
  44. package/dist/quant/job.js +184 -0
  45. package/dist/quant/job.js.map +1 -0
  46. package/dist/quant/register.d.ts +53 -0
  47. package/dist/quant/register.d.ts.map +1 -0
  48. package/dist/quant/register.js +253 -0
  49. package/dist/quant/register.js.map +1 -0
  50. package/dist/quant/registry.d.ts +105 -0
  51. package/dist/quant/registry.d.ts.map +1 -0
  52. package/dist/quant/registry.js +248 -0
  53. package/dist/quant/registry.js.map +1 -0
  54. package/dist/quant/types.d.ts +216 -0
  55. package/dist/quant/types.d.ts.map +1 -0
  56. package/dist/quant/types.js +121 -0
  57. package/dist/quant/types.js.map +1 -0
  58. package/dist/skills-manager/manifest.js +1 -1
  59. package/dist/skills-manager/skills-manifest.json +1 -1
  60. package/dist/widgets/index.d.ts +8 -1
  61. package/dist/widgets/index.d.ts.map +1 -1
  62. package/dist/widgets/index.js +1 -0
  63. package/dist/widgets/index.js.map +1 -1
  64. package/dist/widgets/registry.d.ts +8 -0
  65. package/dist/widgets/registry.d.ts.map +1 -1
  66. package/dist/widgets/registry.js +26 -1
  67. package/dist/widgets/registry.js.map +1 -1
  68. package/dist/widgets/tool.d.ts +14 -4
  69. package/dist/widgets/tool.d.ts.map +1 -1
  70. package/dist/widgets/tool.js +36 -23
  71. package/dist/widgets/tool.js.map +1 -1
  72. package/dist/widgets/turn-cap.d.ts +33 -0
  73. package/dist/widgets/turn-cap.d.ts.map +1 -0
  74. package/dist/widgets/turn-cap.js +119 -0
  75. package/dist/widgets/turn-cap.js.map +1 -0
  76. package/dist/widgets/types.d.ts +33 -5
  77. package/dist/widgets/types.d.ts.map +1 -1
  78. package/dist/widgets/types.js +4 -3
  79. package/dist/widgets/types.js.map +1 -1
  80. package/dist/widgets/widgets/fund-user-wallet.d.ts.map +1 -1
  81. package/dist/widgets/widgets/fund-user-wallet.js +1 -0
  82. package/dist/widgets/widgets/fund-user-wallet.js.map +1 -1
  83. package/dist/widgets/widgets/quant-desk-recommendations.d.ts +52 -0
  84. package/dist/widgets/widgets/quant-desk-recommendations.d.ts.map +1 -0
  85. package/dist/widgets/widgets/quant-desk-recommendations.js +278 -0
  86. package/dist/widgets/widgets/quant-desk-recommendations.js.map +1 -0
  87. package/openclaw.plugin.json +12 -2
  88. package/package.json +4 -3
@@ -1,10 +1,11 @@
1
1
  import type { WidgetLogger } from "./types.js";
2
+ import type { QuantRunReader } from "../quant/types.js";
2
3
  export { WIDGET_SPECS, buildWidgetRegistry } from "./registry.js";
3
4
  export type { WidgetRegistry, WidgetsConfig } from "./registry.js";
4
5
  export { WidgetValidationError } from "./errors.js";
5
6
  export { SHOW_WIDGET_TOOL_NAME, buildShowWidgetDescription, buildShowWidgetParameters, createShowWidgetTool, } from "./tool.js";
6
7
  export type { ShowWidgetTool, ShowWidgetToolResult } from "./tool.js";
7
- export type { RegisteredWidget, WidgetPayload, WidgetResult, WidgetSpec } from "./types.js";
8
+ export type { RegisteredWidget, WidgetHandlerContext, WidgetPayload, WidgetResult, WidgetSpec } from "./types.js";
8
9
  /** The slice of the OpenClaw plugin API this module needs. */
9
10
  export interface WidgetToolPluginApi {
10
11
  registerTool(tool: (ctx: {
@@ -19,6 +20,12 @@ export interface RegisterShowWidgetToolOptions {
19
20
  /** The plugin config `widgets` block: `{ "<widget_type>": boolean }`. */
20
21
  widgetsConfig?: unknown;
21
22
  logger?: WidgetLogger;
23
+ /**
24
+ * The quant desk's run registry (read side), for `quant_desk_recommendations`. Absent when the
25
+ * desk failed to build: the tool still registers, and that type answers with a teaching error
26
+ * telling the model to relay the desk's next steps as text.
27
+ */
28
+ quantRuns?: QuantRunReader;
22
29
  }
23
30
  /**
24
31
  * Register `show_widget` as a plugin tool factory.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/widgets/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE5F,8DAA8D;AAC9D,MAAM,WAAW,mBAAmB;IAClC,YAAY,CACV,IAAI,EAAE,CAAC,GAAG,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,EAC9C,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAC9C,IAAI,CAAC;CACT;AAED,MAAM,WAAW,6BAA6B;IAC5C,GAAG,EAAE,mBAAmB,CAAC;IACzB,yEAAyE;IACzE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,OAAO,CA0BtF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/widgets/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAClE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAElH,8DAA8D;AAC9D,MAAM,WAAW,mBAAmB;IAClC,YAAY,CACV,IAAI,EAAE,CAAC,GAAG,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,EAC9C,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAC9C,IAAI,CAAC;CACT;AAED,MAAM,WAAW,6BAA6B;IAC5C,GAAG,EAAE,mBAAmB,CAAC;IACzB,yEAAyE;IACzE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;;OAIG;IACH,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,6BAA6B,GAAG,OAAO,CA2BtF"}
@@ -26,6 +26,7 @@ export function registerShowWidgetTool(options) {
26
26
  registry,
27
27
  logger,
28
28
  sessionId: ctx?.sessionId,
29
+ handlerContext: options.quantRuns ? { quantRuns: options.quantRuns } : {},
29
30
  }), { names: [SHOW_WIDGET_TOOL_NAME] });
30
31
  logger?.info(`[senpi-widgets] ${SHOW_WIDGET_TOOL_NAME} registered | widget_types=${enabled.join(",")}`);
31
32
  return true;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/widgets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAElE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAmBnB;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAsC;IAC3E,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAChC,2EAA2E;IAC3E,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC;IACxC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,EAAE,IAAI,CACV,6FAA6F,CAC9F,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IACpC,GAAG,CAAC,YAAY,CACd,CAAC,GAA2B,EAAE,EAAE,CAC9B,oBAAoB,CAAC;QACnB,QAAQ;QACR,MAAM;QACN,SAAS,EAAE,GAAG,EAAE,SAAS;KAC1B,CAAC,EACJ,EAAE,KAAK,EAAE,CAAC,qBAAqB,CAAC,EAAE,CACnC,CAAC;IACF,MAAM,EAAE,IAAI,CACV,mBAAmB,qBAAqB,8BAA8B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAC1F,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/widgets/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAInB,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAElE,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,qBAAqB,EACrB,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAyBnB;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAsC;IAC3E,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAChC,2EAA2E;IAC3E,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5D,MAAM,OAAO,GAAG,QAAQ,CAAC,YAAY,EAAE,CAAC;IACxC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,EAAE,IAAI,CACV,6FAA6F,CAC9F,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,yBAAyB,CAAC,QAAQ,CAAC,CAAC;IACpC,GAAG,CAAC,YAAY,CACd,CAAC,GAA2B,EAAE,EAAE,CAC9B,oBAAoB,CAAC;QACnB,QAAQ;QACR,MAAM;QACN,SAAS,EAAE,GAAG,EAAE,SAAS;QACzB,cAAc,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;KAC1E,CAAC,EACJ,EAAE,KAAK,EAAE,CAAC,qBAAqB,CAAC,EAAE,CACnC,CAAC;IACF,MAAM,EAAE,IAAI,CACV,mBAAmB,qBAAqB,8BAA8B,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAC1F,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -20,5 +20,13 @@ export interface WidgetRegistry {
20
20
  get(widgetType: string): RegisteredWidget | undefined;
21
21
  enabledTypes(): string[];
22
22
  }
23
+ /**
24
+ * Resolve the spec list against plugin config.
25
+ *
26
+ * @param config The plugin config `widgets` block (see {@link WidgetsConfig}).
27
+ * @param specs The spec list; defaults to {@link WIDGET_SPECS}. Injected by tests.
28
+ * @throws Error when two specs share a `widget_type`, when two specs declare the same extra
29
+ * parameter name, or when a spec declares `widget_type` as an extra parameter.
30
+ */
23
31
  export declare function buildWidgetRegistry(config?: unknown, specs?: readonly WidgetSpec[]): WidgetRegistry;
24
32
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/widgets/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG/D;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EAAyB,CAAC;AAExE;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,GAAG,IAAI,SAAS,gBAAgB,EAAE,CAAC;IACnC,yEAAyE;IACzE,OAAO,IAAI,SAAS,gBAAgB,EAAE,CAAC;IACvC,+CAA+C;IAC/C,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAC;IACtD,YAAY,IAAI,MAAM,EAAE,CAAC;CAC1B;AAED,wBAAgB,mBAAmB,CACjC,MAAM,CAAC,EAAE,OAAO,EAChB,KAAK,GAAE,SAAS,UAAU,EAAiB,GAC1C,cAAc,CAyBhB"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/widgets/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI/D;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EAAuD,CAAC;AAEtG;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpD,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,GAAG,IAAI,SAAS,gBAAgB,EAAE,CAAC;IACnC,yEAAyE;IACzE,OAAO,IAAI,SAAS,gBAAgB,EAAE,CAAC;IACvC,+CAA+C;IAC/C,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAAC;IACtD,YAAY,IAAI,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,CAAC,EAAE,OAAO,EAChB,KAAK,GAAE,SAAS,UAAU,EAAiB,GAC1C,cAAc,CAyChB"}
@@ -1,11 +1,36 @@
1
1
  import { fundUserWalletSpec } from "./widgets/fund-user-wallet.js";
2
+ import { quantDeskRecommendationsSpec } from "./widgets/quant-desk-recommendations.js";
2
3
  /**
3
4
  * Every widget type this plugin can render. Adding one here adds it to the
4
5
  * `show_widget` enum, to the generated tool description, and to the config
5
6
  * gate — the tool name and the manifest are untouched.
6
7
  */
7
- export const WIDGET_SPECS = [fundUserWalletSpec];
8
+ export const WIDGET_SPECS = [fundUserWalletSpec, quantDeskRecommendationsSpec];
9
+ /**
10
+ * Resolve the spec list against plugin config.
11
+ *
12
+ * @param config The plugin config `widgets` block (see {@link WidgetsConfig}).
13
+ * @param specs The spec list; defaults to {@link WIDGET_SPECS}. Injected by tests.
14
+ * @throws Error when two specs share a `widget_type`, when two specs declare the same extra
15
+ * parameter name, or when a spec declares `widget_type` as an extra parameter.
16
+ */
8
17
  export function buildWidgetRegistry(config, specs = WIDGET_SPECS) {
18
+ // Parameters are one flat object shared by every type, so each extra name has exactly one owner.
19
+ // Checked over ALL specs, not just enabled ones: a clash hidden while one type is disabled would
20
+ // surface the day config flips it on.
21
+ const paramOwner = new Map();
22
+ for (const spec of specs) {
23
+ for (const key of Object.keys(spec.extraParameters ?? {})) {
24
+ if (key === "widget_type") {
25
+ throw new Error(`show_widget: ${spec.widgetType} declares "widget_type" as an extra parameter; it is the shared discriminator`);
26
+ }
27
+ const owner = paramOwner.get(key);
28
+ if (owner) {
29
+ throw new Error(`show_widget: parameter "${key}" is declared by both ${owner} and ${spec.widgetType}; each name has one owner`);
30
+ }
31
+ paramOwner.set(key, spec.widgetType);
32
+ }
33
+ }
9
34
  const gate = config && typeof config === "object" && !Array.isArray(config)
10
35
  ? config
11
36
  : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/widgets/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAA0B,CAAC,kBAAkB,CAAC,CAAC;AAmBxE,MAAM,UAAU,mBAAmB,CACjC,MAAgB,EAChB,QAA+B,YAAY;IAE3C,MAAM,IAAI,GACR,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5D,CAAC,CAAE,MAAkC;QACrC,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,OAAO,GAAuB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvD,GAAG,IAAI;QACP,OAAO,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,KAAK;KAC3C,CAAC,CAAC,CAAC;IACJ,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACnD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,4EAA4E;QAC5E,sEAAsE;QACtE,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,sDAAsD,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC;QAC9F,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO;QAClB,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO;QACtB,GAAG,EAAE,CAAC,UAAkB,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;QACnD,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;KACrD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/widgets/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAC;AAEvF;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAA0B,CAAC,kBAAkB,EAAE,4BAA4B,CAAC,CAAC;AAmBtG;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,MAAgB,EAChB,QAA+B,YAAY;IAE3C,iGAAiG;IACjG,iGAAiG;IACjG,sCAAsC;IACtC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,IAAI,EAAE,CAAC,EAAE,CAAC;YAC1D,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,CAAC,UAAU,+EAA+E,CAAC,CAAC;YAClI,CAAC;YACD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAClC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,2BAA2B,GAAG,yBAAyB,KAAK,QAAQ,IAAI,CAAC,UAAU,2BAA2B,CAAC,CAAC;YAClI,CAAC;YACD,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GACR,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAC5D,CAAC,CAAE,MAAkC;QACrC,CAAC,CAAC,SAAS,CAAC;IAChB,MAAM,OAAO,GAAuB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvD,GAAG,IAAI;QACP,OAAO,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,KAAK;KAC3C,CAAC,CAAC,CAAC;IACJ,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;IACnD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,4EAA4E;QAC5E,sEAAsE;QACtE,IAAI,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,sDAAsD,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC;QAC9F,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO;QAClB,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO;QACtB,GAAG,EAAE,CAAC,UAAkB,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC;QACnD,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;KACrD,CAAC;AACJ,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { WidgetRegistry } from "./registry.js";
2
- import type { WidgetLogger, WidgetPayload } from "./types.js";
2
+ import type { WidgetHandlerContext, WidgetLogger, WidgetPayload } from "./types.js";
3
3
  /**
4
4
  * The plugin's single agent tool. The name is static — new widget types are
5
5
  * new `widget_type` enum values, never new tools — so it is declared once in
@@ -24,25 +24,35 @@ export interface CreateShowWidgetToolOptions {
24
24
  logger?: WidgetLogger;
25
25
  /** Ephemeral session id from the plugin tool factory context; logged only. */
26
26
  sessionId?: string;
27
+ /** Collaborators handed to every handler (e.g. the quant run reader). Defaults to `{}`. */
28
+ handlerContext?: WidgetHandlerContext;
27
29
  }
28
30
  /**
29
31
  * Tool description, generated from the enabled specs. Nothing else teaches the
30
32
  * model about these cards, so this text carries the condition that should make
31
33
  * it call the tool, not just the shape of the call.
34
+ *
35
+ * The shared header claims nothing that is true of only one type: how a card is
36
+ * acted on (`card:`) and which fields it takes (`fields:`) are stated per type,
37
+ * because not every card has a button and not every type takes widget_type only.
32
38
  */
33
39
  export declare function buildShowWidgetDescription(registry: WidgetRegistry): string;
34
40
  /**
35
41
  * Declared JSON schema: one flat object, no unions at any depth.
36
42
  *
37
43
  * OpenClaw flattens top-level unions, Gemini flattens nested ones, and OpenAI
38
- * strict mode rejects a schema containing one anywhere. `widget_type` is the
39
- * only parameter, and it is required.
44
+ * strict mode rejects a schema containing one anywhere. So there is no per-type
45
+ * branch: `widget_type` is the one required property, and every enabled spec's
46
+ * `extraParameters` are merged in beside it as optional properties. Each such
47
+ * property belongs to one type (the registry refuses a shared name) and is
48
+ * validated by that type's handler; `rejectExtraFields` refuses one sent with
49
+ * any other type.
40
50
  */
41
51
  export declare function buildShowWidgetParameters(registry: WidgetRegistry): Record<string, unknown>;
42
52
  /**
43
53
  * Build the `show_widget` tool for one agent turn. `sessionId` comes from the
44
54
  * plugin tool factory context and is used for logging only — nothing about the
45
- * result depends on it.
55
+ * result depends on it. `handlerContext` is passed to every handler as-is.
46
56
  */
47
57
  export declare function createShowWidgetTool(options: CreateShowWidgetToolOptions): ShowWidgetTool;
48
58
  //# sourceMappingURL=tool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/widgets/tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAoB,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AAInD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC7E;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAsB3E;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiB3F;AAmED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,cAAc,CAkCzF"}
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../src/widgets/tool.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAoB,oBAAoB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEtG;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,gBAAgB,CAAC;AAInD,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC7E;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2FAA2F;IAC3F,cAAc,CAAC,EAAE,oBAAoB,CAAC;CACvC;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAwB3E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAc3F;AAuED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,cAAc,CAmCzF"}
@@ -10,6 +10,10 @@ const WIDGET_TYPE_PARAM = "widget_type";
10
10
  * Tool description, generated from the enabled specs. Nothing else teaches the
11
11
  * model about these cards, so this text carries the condition that should make
12
12
  * it call the tool, not just the shape of the call.
13
+ *
14
+ * The shared header claims nothing that is true of only one type: how a card is
15
+ * acted on (`card:`) and which fields it takes (`fields:`) are stated per type,
16
+ * because not every card has a button and not every type takes widget_type only.
13
17
  */
14
18
  export function buildShowWidgetDescription(registry) {
15
19
  const widgets = registry.enabled();
@@ -17,16 +21,18 @@ export function buildShowWidgetDescription(registry) {
17
21
  return "Render a Senpi UI card in the user's chat.\n\nNo widget types are enabled on this deployment.";
18
22
  }
19
23
  const lines = [
20
- "Render a Senpi UI card in the user's chat. The card is live UI: its button runs the flow, so showing it is how the user acts.",
24
+ "Render a Senpi UI card in the user's chat.",
21
25
  "",
22
26
  "Call it yourself as part of your answer — the user does not have to ask for a card. Each type below states when to call it; the examples illustrate that rule, they are not a checklist to match.",
23
27
  "",
24
- `Pass ${WIDGET_TYPE_PARAM} and nothing else.`,
28
+ `Pass ${WIDGET_TYPE_PARAM} plus the fields listed for that type, and nothing else.`,
25
29
  "",
26
30
  "Widget types:",
27
31
  ];
28
32
  for (const widget of widgets) {
29
33
  lines.push(`- ${widget.widgetType}: ${widget.description}`);
34
+ lines.push(` card: ${widget.affordance}`);
35
+ lines.push(` fields: ${widget.fields ?? `none — ${WIDGET_TYPE_PARAM} only`}`);
30
36
  lines.push(` when: ${widget.callWhen}`);
31
37
  lines.push(` not this card: ${widget.notFor}`);
32
38
  lines.push(" for example:");
@@ -38,26 +44,28 @@ export function buildShowWidgetDescription(registry) {
38
44
  * Declared JSON schema: one flat object, no unions at any depth.
39
45
  *
40
46
  * OpenClaw flattens top-level unions, Gemini flattens nested ones, and OpenAI
41
- * strict mode rejects a schema containing one anywhere. `widget_type` is the
42
- * only parameter, and it is required.
47
+ * strict mode rejects a schema containing one anywhere. So there is no per-type
48
+ * branch: `widget_type` is the one required property, and every enabled spec's
49
+ * `extraParameters` are merged in beside it as optional properties. Each such
50
+ * property belongs to one type (the registry refuses a shared name) and is
51
+ * validated by that type's handler; `rejectExtraFields` refuses one sent with
52
+ * any other type.
43
53
  */
44
54
  export function buildShowWidgetParameters(registry) {
45
55
  const widgets = registry.enabled();
46
56
  if (widgets.length === 0) {
47
57
  throw new Error("show_widget has no enabled widget types; do not register the tool");
48
58
  }
49
- return {
50
- type: "object",
51
- properties: {
52
- [WIDGET_TYPE_PARAM]: {
53
- type: "string",
54
- enum: widgets.map((w) => w.widgetType),
55
- description: "Which card to render.",
56
- },
59
+ const properties = {
60
+ [WIDGET_TYPE_PARAM]: {
61
+ type: "string",
62
+ enum: widgets.map((w) => w.widgetType),
63
+ description: "Which card to render.",
57
64
  },
58
- required: [WIDGET_TYPE_PARAM],
59
- additionalProperties: false,
60
65
  };
66
+ for (const widget of widgets)
67
+ Object.assign(properties, widget.extraParameters ?? {});
68
+ return { type: "object", properties, required: [WIDGET_TYPE_PARAM], additionalProperties: false };
61
69
  }
62
70
  function availableTypesSentence(registry) {
63
71
  const types = registry.enabledTypes();
@@ -90,24 +98,28 @@ function resolveWidget(registry, args) {
90
98
  return widget;
91
99
  }
92
100
  /**
93
- * The tool takes one argument, so any other key is a field the model invented.
94
- * Every one is named in a single message: the correction is the same for all of
95
- * them, and the model can apply it in one retry.
101
+ * A type takes `widget_type` plus its own `extraParameters`, so any other key is
102
+ * a field the model invented — or one that belongs to another type, which the
103
+ * merged schema cannot refuse on its own. Every one is named in a single
104
+ * message, with the fields this type does take: the correction is the same for
105
+ * all of them, and the model can apply it in one retry.
96
106
  */
97
107
  function rejectExtraFields(widget, args) {
98
- const unexpected = Object.keys(args).filter((key) => key !== WIDGET_TYPE_PARAM);
108
+ const allowed = [WIDGET_TYPE_PARAM, ...Object.keys(widget.extraParameters ?? {})];
109
+ const unexpected = Object.keys(args).filter((key) => !allowed.includes(key));
99
110
  if (unexpected.length === 0)
100
111
  return;
112
+ const takes = allowed.length === 1 ? `${WIDGET_TYPE_PARAM} only` : `${allowed.join(", ")} for ${widget.widgetType}`;
101
113
  throw new WidgetValidationError(`show_widget failed for ${WIDGET_TYPE_PARAM} "${widget.widgetType}": unexpected fields: ` +
102
- `${unexpected.join(", ")}. show_widget takes ${WIDGET_TYPE_PARAM} only — drop them and call it again.`, widget.widgetType, unexpected);
114
+ `${unexpected.join(", ")}. show_widget takes ${takes} — drop them and call it again.`, widget.widgetType, unexpected);
103
115
  }
104
116
  /**
105
117
  * Build the `show_widget` tool for one agent turn. `sessionId` comes from the
106
118
  * plugin tool factory context and is used for logging only — nothing about the
107
- * result depends on it.
119
+ * result depends on it. `handlerContext` is passed to every handler as-is.
108
120
  */
109
121
  export function createShowWidgetTool(options) {
110
- const { registry, logger, sessionId } = options;
122
+ const { registry, logger, sessionId, handlerContext } = options;
111
123
  const session = sessionId ?? "(unknown)";
112
124
  return {
113
125
  name: SHOW_WIDGET_TOOL_NAME,
@@ -118,8 +130,9 @@ export function createShowWidgetTool(options) {
118
130
  const args = toArgs(params);
119
131
  const widget = resolveWidget(registry, args);
120
132
  rejectExtraFields(widget, args);
121
- const result = await widget.handler();
122
- logger?.info(`[senpi-widgets] widget shown | widget_type=${widget.widgetType} widget_version=${widget.widgetVersion} session=${session}`);
133
+ const result = await widget.handler(args, handlerContext ?? {});
134
+ logger?.info(`[senpi-widgets] widget shown | widget_type=${widget.widgetType} widget_version=${widget.widgetVersion}` +
135
+ `${typeof args.run_id === "string" ? ` run_id=${args.run_id}` : ""} session=${session}`);
123
136
  return {
124
137
  content: [{ type: "text", text: result.text }],
125
138
  details: result.payload,
@@ -1 +1 @@
1
- {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/widgets/tool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../src/widgets/tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /** How long a run's entry is kept after its last touch. */
2
+ export declare const TURN_CAP_TTL_MS: number;
3
+ /** The reason the model reads on a blocked call. */
4
+ export declare const TURN_CAP_BLOCK_REASON = "[E_WIDGET_TURN_CAP] recommendation cards were already shown in this answer; fold anything else into text.";
5
+ /** The cap's two hook bodies, exposed for tests. */
6
+ export interface QuantWidgetTurnCap {
7
+ beforeToolCall(event: unknown, ctx?: unknown): {
8
+ block: true;
9
+ blockReason: string;
10
+ } | undefined;
11
+ afterToolCall(event: unknown, ctx?: unknown): void;
12
+ trackedRuns(): number;
13
+ }
14
+ /** Build the cap's state machine. `now` is injected so expiry is testable. */
15
+ export declare function createQuantWidgetTurnCap(opts: {
16
+ now(): number;
17
+ ttlMs?: number;
18
+ }): QuantWidgetTurnCap;
19
+ /** The slice of the plugin API the cap needs. */
20
+ export interface TurnCapPluginApi {
21
+ on(hookName: string, handler: (...args: unknown[]) => unknown, opts?: {
22
+ priority?: number;
23
+ }): void;
24
+ }
25
+ /** Register the cap on `before_tool_call` / `after_tool_call`. Fails open on any internal error. */
26
+ export declare function registerQuantWidgetTurnCap(api: TurnCapPluginApi, opts: {
27
+ now(): number;
28
+ logger?: {
29
+ info(...a: unknown[]): void;
30
+ warn(...a: unknown[]): void;
31
+ };
32
+ }): QuantWidgetTurnCap;
33
+ //# sourceMappingURL=turn-cap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-cap.d.ts","sourceRoot":"","sources":["../../src/widgets/turn-cap.ts"],"names":[],"mappings":"AA2BA,2DAA2D;AAC3D,eAAO,MAAM,eAAe,QAAc,CAAC;AAC3C,oDAAoD;AACpD,eAAO,MAAM,qBAAqB,8GAC2E,CAAC;AAe9G,oDAAoD;AACpD,MAAM,WAAW,kBAAkB;IACjC,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;IAChG,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACnD,WAAW,IAAI,MAAM,CAAC;CACvB;AAmBD,8EAA8E;AAC9E,wBAAgB,wBAAwB,CAAC,IAAI,EAAE;IAAE,GAAG,IAAI,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,kBAAkB,CAwCpG;AAED,iDAAiD;AACjD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACpG;AAED,oGAAoG;AACpG,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE;IAAE,GAAG,IAAI,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;KAAE,CAAA;CAAE,GAC7F,kBAAkB,CAoBpB"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Per-run cap on `quant_desk_recommendations` (spec D8).
3
+ *
4
+ * `maxItems` bounds one call; a model that wants seven cards parallelises instead (field finding
5
+ * 4). Tool factories carry no run id, hooks do, so the cap lives in `before_tool_call`: while a
6
+ * quant card call is in flight or has succeeded in an agent run, any further one in that run is
7
+ * blocked with a teaching reason. `after_tool_call` makes the cap exact rather than a counter: a
8
+ * FAILED call (a mistyped run id) frees the slot so the corrected retry renders, and the after-event
9
+ * of a call the cap itself blocked is ignored (matched by toolCallId). Entries expire after 10 min.
10
+ * No run id from the host → fail open. The hooks never throw into the tool pipeline.
11
+ *
12
+ * Host shapes (OpenClaw `PluginHookBeforeToolCallEvent` / `PluginHookAfterToolCallEvent` /
13
+ * `PluginHookToolContext`): both the event and the ctx carry optional `runId` and `toolCallId`, so
14
+ * the event is read first and the ctx is the fallback. The event carries `toolName` and `params`;
15
+ * the after-event adds `result` and `error` (a string, set when the tool threw or returned an error
16
+ * result — `show_widget` throws on every refusal). A `{ block, blockReason }` return from
17
+ * `before_tool_call` stops the call and hands `blockReason` to the model as the tool error.
18
+ *
19
+ * Parallel calls in one assistant message (the fleet model's way past `maxItems`) all reach
20
+ * `before_tool_call` before any `after_tool_call`; the in-flight `pendingCallId` is what blocks
21
+ * the second one in that window.
22
+ */
23
+ import { SHOW_WIDGET_TOOL_NAME } from "./tool.js";
24
+ const QUANT_WIDGET_TYPE = "quant_desk_recommendations";
25
+ /** The call id recorded when the host supplies none; it cannot identify a call on its own. */
26
+ const UNKNOWN_CALL_ID = "(unknown)";
27
+ /** How long a run's entry is kept after its last touch. */
28
+ export const TURN_CAP_TTL_MS = 10 * 60_000;
29
+ /** The reason the model reads on a blocked call. */
30
+ export const TURN_CAP_BLOCK_REASON = "[E_WIDGET_TURN_CAP] recommendation cards were already shown in this answer; fold anything else into text.";
31
+ function str(x) {
32
+ return typeof x === "string" && x.length > 0 ? x : undefined;
33
+ }
34
+ function read(event, ctx) {
35
+ const ev = (event && typeof event === "object" ? event : {});
36
+ const c = (ctx && typeof ctx === "object" ? ctx : {});
37
+ const params = ev.params && typeof ev.params === "object" ? ev.params : undefined;
38
+ const runId = str(ev.runId) ?? str(c.runId);
39
+ return {
40
+ ev,
41
+ ...(runId ? { runId } : {}),
42
+ callId: str(ev.toolCallId) ?? str(c.toolCallId) ?? UNKNOWN_CALL_ID,
43
+ isQuant: ev.toolName === SHOW_WIDGET_TOOL_NAME && params?.widget_type === QUANT_WIDGET_TYPE,
44
+ };
45
+ }
46
+ /** Build the cap's state machine. `now` is injected so expiry is testable. */
47
+ export function createQuantWidgetTurnCap(opts) {
48
+ const ttl = opts.ttlMs ?? TURN_CAP_TTL_MS;
49
+ const runs = new Map();
50
+ const sweep = () => {
51
+ const cutoff = opts.now() - ttl;
52
+ for (const [k, e] of runs)
53
+ if (e.touchedAt <= cutoff)
54
+ runs.delete(k);
55
+ };
56
+ return {
57
+ beforeToolCall(event, ctx) {
58
+ const { runId, callId, isQuant } = read(event, ctx);
59
+ if (!isQuant || !runId)
60
+ return undefined;
61
+ sweep();
62
+ const entry = runs.get(runId);
63
+ if (entry && (entry.shown || entry.pendingCallId !== undefined)) {
64
+ entry.touchedAt = opts.now();
65
+ return { block: true, blockReason: TURN_CAP_BLOCK_REASON };
66
+ }
67
+ runs.set(runId, { shown: false, pendingCallId: callId, touchedAt: opts.now() });
68
+ return undefined;
69
+ },
70
+ afterToolCall(event, ctx) {
71
+ // No `isQuant` gate here: only a quant call can have set `pendingCallId`, so the toolCallId
72
+ // match is the identity. Re-deriving it from `params` would leave the entry pending forever
73
+ // when a host's after-event omits or empties them. The one exception is a call the host gave
74
+ // no id: then "(unknown)" matches any id-less event, so the tool itself must be the quant one.
75
+ const { ev, runId, callId, isQuant } = read(event, ctx);
76
+ if (!runId)
77
+ return;
78
+ const entry = runs.get(runId);
79
+ if (!entry || entry.pendingCallId !== callId)
80
+ return;
81
+ if (callId === UNKNOWN_CALL_ID && !isQuant)
82
+ return;
83
+ if (ev.error !== undefined && ev.error !== null && ev.error !== "") {
84
+ runs.delete(runId);
85
+ return;
86
+ }
87
+ entry.shown = true;
88
+ entry.pendingCallId = undefined;
89
+ entry.touchedAt = opts.now();
90
+ },
91
+ trackedRuns: () => runs.size,
92
+ };
93
+ }
94
+ /** Register the cap on `before_tool_call` / `after_tool_call`. Fails open on any internal error. */
95
+ export function registerQuantWidgetTurnCap(api, opts) {
96
+ const cap = createQuantWidgetTurnCap(opts);
97
+ api.on("before_tool_call", (event, ctx) => {
98
+ try {
99
+ const verdict = cap.beforeToolCall(event, ctx);
100
+ if (verdict)
101
+ opts.logger?.info(`[senpi-widgets] turn cap blocked a second ${QUANT_WIDGET_TYPE} call`);
102
+ return verdict;
103
+ }
104
+ catch (err) {
105
+ opts.logger?.warn(`[senpi-widgets] turn cap failed open: ${err instanceof Error ? err.message : String(err)}`);
106
+ return undefined;
107
+ }
108
+ });
109
+ api.on("after_tool_call", (event, ctx) => {
110
+ try {
111
+ cap.afterToolCall(event, ctx);
112
+ }
113
+ catch {
114
+ // the cap never breaks the tool pipeline
115
+ }
116
+ });
117
+ return cap;
118
+ }
119
+ //# sourceMappingURL=turn-cap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turn-cap.js","sourceRoot":"","sources":["../../src/widgets/turn-cap.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,12 @@
2
2
  * Widget spec types.
3
3
  *
4
4
  * A widget spec is the single source for one `widget_type`: the text that
5
- * teaches the model when to reach for the card, and the handler that builds
6
- * the result. The `show_widget` descriptor (enum + description) is generated
7
- * from the spec list, so the two cannot drift.
5
+ * teaches the model when to reach for the card, the extra arguments it takes,
6
+ * and the handler that builds the result. The `show_widget` descriptor (enum,
7
+ * merged parameters, description) is generated from the spec list, so the two
8
+ * cannot drift.
8
9
  */
10
+ import type { QuantRunReader } from "../quant/types.js";
9
11
  /** Rendered by the client. Always carries the three shared keys. */
10
12
  export interface WidgetPayload {
11
13
  readonly widget_type: string;
@@ -18,6 +20,14 @@ export interface WidgetResult {
18
20
  /** Short line for the agent — what happened and what not to do next. */
19
21
  readonly text: string;
20
22
  }
23
+ /**
24
+ * Collaborators a handler may read, injected at registration. Optional so a deployment without a
25
+ * collaborator still registers the tool; a handler that needs one fails with a teaching error.
26
+ */
27
+ export interface WidgetHandlerContext {
28
+ /** The quant desk's stored runs (`src/quant/registry.ts`), read-only. Absent when the desk failed to build. */
29
+ readonly quantRuns?: QuantRunReader;
30
+ }
21
31
  export interface WidgetSpec {
22
32
  readonly widgetType: string;
23
33
  /** Bumped when the payload shape changes; the client falls back on unknown versions. */
@@ -37,8 +47,26 @@ export interface WidgetSpec {
37
47
  readonly notFor: string;
38
48
  /** Situations illustrating the condition. One line each, reproduced verbatim. */
39
49
  readonly examples: readonly string[];
40
- /** Takes no arguments: `show_widget` accepts `widget_type` and nothing else. */
41
- readonly handler: () => WidgetResult | Promise<WidgetResult>;
50
+ /** How the rendered card is acted on — one line in the description. Per type: not every card has a button. */
51
+ readonly affordance: string;
52
+ /** One line naming the fields beyond widget_type, reproduced in the description. Absent = widget_type only. */
53
+ readonly fields?: string;
54
+ /**
55
+ * JSON-schema properties beyond widget_type, merged into the ONE flat parameter object. Each name
56
+ * has one owner across all specs (checked at registry build) and none may be `widget_type`.
57
+ * Flat and union-free, like the rest of the schema (see `buildShowWidgetParameters`).
58
+ */
59
+ readonly extraParameters?: Readonly<Record<string, Readonly<Record<string, unknown>>>>;
60
+ /**
61
+ * Builds the result. `args` has already passed the extra-field check for this type (only
62
+ * `widget_type` and this spec's `extraParameters` keys are present); the handler still validates
63
+ * their values, since the schema is advisory to the model and the handler is the real boundary.
64
+ *
65
+ * @param args The call's arguments, `widget_type` included.
66
+ * @param ctx Collaborators injected at registration; a handler needing an absent one throws a
67
+ * teaching error (a `WidgetValidationError`) naming the fallback.
68
+ */
69
+ readonly handler: (args: Readonly<Record<string, unknown>>, ctx: WidgetHandlerContext) => WidgetResult | Promise<WidgetResult>;
42
70
  }
43
71
  /** A spec plus its resolved on/off state from plugin config. */
44
72
  export interface RegisteredWidget extends WidgetSpec {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/widgets/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC9D;AAED,gEAAgE;AAChE,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,mEAAmE;IACnE,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/widgets/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,oEAAoE;AACpE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;IAChC,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,+GAA+G;IAC/G,QAAQ,CAAC,SAAS,CAAC,EAAE,cAAc,CAAC;CACrC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,uEAAuE;IACvE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,iFAAiF;IACjF,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,8GAA8G;IAC9G,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,+GAA+G;IAC/G,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACvF;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,EAAE,CAChB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACvC,GAAG,EAAE,oBAAoB,KACtB,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC3C;AAED,gEAAgE;AAChE,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,mEAAmE;IACnE,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAClC"}
@@ -2,9 +2,10 @@
2
2
  * Widget spec types.
3
3
  *
4
4
  * A widget spec is the single source for one `widget_type`: the text that
5
- * teaches the model when to reach for the card, and the handler that builds
6
- * the result. The `show_widget` descriptor (enum + description) is generated
7
- * from the spec list, so the two cannot drift.
5
+ * teaches the model when to reach for the card, the extra arguments it takes,
6
+ * and the handler that builds the result. The `show_widget` descriptor (enum,
7
+ * merged parameters, description) is generated from the spec list, so the two
8
+ * cannot drift.
8
9
  */
9
10
  export {};
10
11
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/widgets/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/widgets/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -1 +1 @@
1
- {"version":3,"file":"fund-user-wallet.d.ts","sourceRoot":"","sources":["../../../src/widgets/widgets/fund-user-wallet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,UA6BhC,CAAC"}
1
+ {"version":3,"file":"fund-user-wallet.d.ts","sourceRoot":"","sources":["../../../src/widgets/widgets/fund-user-wallet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAK9C;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,UA8BhC,CAAC"}
@@ -15,6 +15,7 @@ export const fundUserWalletSpec = {
15
15
  description: "Opens Senpi's deposit flow for the user's OWN Senpi wallet, the one they deposit into from outside. " +
16
16
  "The card owns the address, the networks and the deposit copy — never write a deposit address, a QR code " +
17
17
  "or a network list in chat.",
18
+ affordance: "live UI: its button runs the flow, so showing it is how the user acts.",
18
19
  callWhen: "Call it whenever you want money to arrive in the user's own Senpi wallet, whether or not the user " +
19
20
  "mentions a deposit or a card.",
20
21
  notFor: "Funding, topping up or adding margin to a STRATEGY — a strategy is funded from the user's own wallet " +
@@ -1 +1 @@
1
- {"version":3,"file":"fund-user-wallet.js","sourceRoot":"","sources":["../../../src/widgets/widgets/fund-user-wallet.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,kBAAkB,CAAC;AACvC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAe;IAC5C,UAAU,EAAE,WAAW;IACvB,aAAa,EAAE,cAAc;IAC7B,WAAW,EACT,sGAAsG;QACtG,0GAA0G;QAC1G,4BAA4B;IAC9B,QAAQ,EACN,oGAAoG;QACpG,+BAA+B;IACjC,MAAM,EACJ,uGAAuG;QACvG,iEAAiE;IACnE,QAAQ,EAAE;QACR,kFAAkF;QAClF,sCAAsC;QACtC,2FAA2F;QAC3F,4FAA4F;KAC7F;IACD,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QACd,OAAO,EAAE;YACP,WAAW,EAAE,WAAW;YACxB,cAAc,EAAE,cAAc;YAC9B,MAAM,EAAE,OAAO;SAChB;QACD,IAAI,EACF,0DAA0D;YAC1D,wEAAwE;KAC3E,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"fund-user-wallet.js","sourceRoot":"","sources":["../../../src/widgets/widgets/fund-user-wallet.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,GAAG,kBAAkB,CAAC;AACvC,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAe;IAC5C,UAAU,EAAE,WAAW;IACvB,aAAa,EAAE,cAAc;IAC7B,WAAW,EACT,sGAAsG;QACtG,0GAA0G;QAC1G,4BAA4B;IAC9B,UAAU,EAAE,wEAAwE;IACpF,QAAQ,EACN,oGAAoG;QACpG,+BAA+B;IACjC,MAAM,EACJ,uGAAuG;QACvG,iEAAiE;IACnE,QAAQ,EAAE;QACR,kFAAkF;QAClF,sCAAsC;QACtC,2FAA2F;QAC3F,4FAA4F;KAC7F;IACD,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QACd,OAAO,EAAE;YACP,WAAW,EAAE,WAAW;YACxB,cAAc,EAAE,cAAc;YAC9B,MAAM,EAAE,OAAO;SAChB;QACD,IAAI,EACF,0DAA0D;YAC1D,wEAAwE;KAC3E,CAAC;CACH,CAAC"}