@senpi/runtime 3.0.81 → 3.0.82

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/actions/decision-engine.d.ts +16 -0
  2. package/dist/actions/decision-engine.d.ts.map +1 -1
  3. package/dist/actions/decision-engine.js +137 -1
  4. package/dist/actions/decision-engine.js.map +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +1 -5
  7. package/dist/index.js.map +1 -1
  8. package/dist/skills-manager/manifest.d.ts.map +1 -1
  9. package/dist/skills-manager/manifest.js +1 -0
  10. package/dist/skills-manager/manifest.js.map +1 -1
  11. package/dist/skills-manager/skills-manifest.json +1 -0
  12. package/dist/widgets/errors.d.ts +3 -15
  13. package/dist/widgets/errors.d.ts.map +1 -1
  14. package/dist/widgets/errors.js +3 -20
  15. package/dist/widgets/errors.js.map +1 -1
  16. package/dist/widgets/index.d.ts +3 -10
  17. package/dist/widgets/index.d.ts.map +1 -1
  18. package/dist/widgets/index.js +3 -6
  19. package/dist/widgets/index.js.map +1 -1
  20. package/dist/widgets/registry.d.ts.map +1 -1
  21. package/dist/widgets/registry.js +10 -3
  22. package/dist/widgets/registry.js.map +1 -1
  23. package/dist/widgets/tool.d.ts +6 -9
  24. package/dist/widgets/tool.d.ts.map +1 -1
  25. package/dist/widgets/tool.js +37 -147
  26. package/dist/widgets/tool.js.map +1 -1
  27. package/dist/widgets/types.d.ts +20 -58
  28. package/dist/widgets/types.d.ts.map +1 -1
  29. package/dist/widgets/types.js +4 -4
  30. package/dist/widgets/widgets/fund-user-wallet.d.ts +4 -5
  31. package/dist/widgets/widgets/fund-user-wallet.d.ts.map +1 -1
  32. package/dist/widgets/widgets/fund-user-wallet.js +27 -67
  33. package/dist/widgets/widgets/fund-user-wallet.js.map +1 -1
  34. package/openclaw.plugin.json +1 -4
  35. package/package.json +2 -3
  36. package/dist/widgets/strategy-lookup.d.ts +0 -39
  37. package/dist/widgets/strategy-lookup.d.ts.map +0 -1
  38. package/dist/widgets/strategy-lookup.js +0 -70
  39. package/dist/widgets/strategy-lookup.js.map +0 -1
  40. package/dist/widgets/widgets/fund-strategy-wallet.d.ts +0 -13
  41. package/dist/widgets/widgets/fund-strategy-wallet.d.ts.map +0 -1
  42. package/dist/widgets/widgets/fund-strategy-wallet.js +0 -139
  43. package/dist/widgets/widgets/fund-strategy-wallet.js.map +0 -1
  44. package/skills/senpi-widgets/SKILL.md +0 -167
@@ -1,11 +1,10 @@
1
- import { fundStrategyWalletSpec } from "./widgets/fund-strategy-wallet.js";
2
1
  import { fundUserWalletSpec } from "./widgets/fund-user-wallet.js";
3
2
  /**
4
3
  * Every widget type this plugin can render. Adding one here adds it to the
5
4
  * `show_widget` enum, to the generated tool description, and to the config
6
5
  * gate — the tool name and the manifest are untouched.
7
6
  */
8
- export const WIDGET_SPECS = [fundUserWalletSpec, fundStrategyWalletSpec];
7
+ export const WIDGET_SPECS = [fundUserWalletSpec];
9
8
  export function buildWidgetRegistry(config, specs = WIDGET_SPECS) {
10
9
  const gate = config && typeof config === "object" && !Array.isArray(config)
11
10
  ? config
@@ -14,7 +13,15 @@ export function buildWidgetRegistry(config, specs = WIDGET_SPECS) {
14
13
  ...spec,
15
14
  enabled: gate?.[spec.widgetType] !== false,
16
15
  }));
17
- const byType = new Map(widgets.map((w) => [w.widgetType, w]));
16
+ const byType = new Map();
17
+ for (const widget of widgets) {
18
+ // The enum and this map both key on the type, so a duplicate would shadow a
19
+ // widget and put the same value in the enum twice instead of failing.
20
+ if (byType.has(widget.widgetType)) {
21
+ throw new Error(`show_widget: two widget specs declare widget_type "${widget.widgetType}"`);
22
+ }
23
+ byType.set(widget.widgetType, widget);
24
+ }
18
25
  const enabled = widgets.filter((w) => w.enabled);
19
26
  return {
20
27
  all: () => widgets,
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/widgets/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAA0B,CAAC,kBAAkB,EAAE,sBAAsB,CAAC,CAAC;AAmBhG,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,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,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;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,5 +1,5 @@
1
1
  import type { WidgetRegistry } from "./registry.js";
2
- import type { StrategyLookup, WidgetLogger, WidgetPayload } from "./types.js";
2
+ import type { 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,22 +24,19 @@ 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
- /** Backend a widget validates addresses against. Absent = those widgets fail closed. */
28
- strategies?: StrategyLookup;
29
27
  }
30
28
  /**
31
- * Tool description, generated from the enabled specs. This is the text the
32
- * model selects a `widget_type` on, so it carries the per-type field list that
33
- * the flat JSON schema cannot express.
29
+ * Tool description, generated from the enabled specs. Nothing else teaches the
30
+ * model about these cards, so this text carries the condition that should make
31
+ * it call the tool, not just the shape of the call.
34
32
  */
35
33
  export declare function buildShowWidgetDescription(registry: WidgetRegistry): string;
36
34
  /**
37
35
  * Declared JSON schema: one flat object, no unions at any depth.
38
36
  *
39
37
  * OpenClaw flattens top-level unions, Gemini flattens nested ones, and OpenAI
40
- * strict mode rejects a schema containing one anywhere — so a discriminated
41
- * union on `widget_type` would buy nothing. Only `widget_type` is required;
42
- * per-widget requiredness is enforced in `execute()`.
38
+ * strict mode rejects a schema containing one anywhere. `widget_type` is the
39
+ * only parameter, and it is required.
43
40
  */
44
41
  export declare function buildShowWidgetParameters(registry: WidgetRegistry): Record<string, unknown>;
45
42
  /**
@@ -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,EAEV,cAAc,EAEd,YAAY,EACZ,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB;;;;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,wFAAwF;IACxF,UAAU,CAAC,EAAE,cAAc,CAAC;CAC7B;AAQD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAuB3E;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyD3F;AAyID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,2BAA2B,GAAG,cAAc,CA2CzF"}
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,4 +1,4 @@
1
- import { WidgetLookupError, WidgetValidationError } from "./errors.js";
1
+ import { WidgetValidationError } from "./errors.js";
2
2
  /**
3
3
  * The plugin's single agent tool. The name is static — new widget types are
4
4
  * new `widget_type` enum values, never new tools — so it is declared once in
@@ -6,38 +6,31 @@ import { WidgetLookupError, WidgetValidationError } from "./errors.js";
6
6
  */
7
7
  export const SHOW_WIDGET_TOOL_NAME = "show_widget";
8
8
  const WIDGET_TYPE_PARAM = "widget_type";
9
- function fieldLine(field) {
10
- const parts = [`${field.required ? "required" : "optional"} ${field.type}`];
11
- if (field.maxLength !== undefined)
12
- parts.push(`max ${field.maxLength} chars`);
13
- return ` ${field.name} (${parts.join(", ")}): ${field.description}`;
14
- }
15
9
  /**
16
- * Tool description, generated from the enabled specs. This is the text the
17
- * model selects a `widget_type` on, so it carries the per-type field list that
18
- * the flat JSON schema cannot express.
10
+ * Tool description, generated from the enabled specs. Nothing else teaches the
11
+ * model about these cards, so this text carries the condition that should make
12
+ * it call the tool, not just the shape of the call.
19
13
  */
20
14
  export function buildShowWidgetDescription(registry) {
21
15
  const widgets = registry.enabled();
16
+ if (widgets.length === 0) {
17
+ return "Render a Senpi UI card in the user's chat.\n\nNo widget types are enabled on this deployment.";
18
+ }
22
19
  const lines = [
23
- "Render a Senpi UI card in the user's chat, for cases where a card communicates better than text.",
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
21
  "",
25
- `Pass ${WIDGET_TYPE_PARAM} plus only the fields listed for that type. Any other field is rejected.`,
22
+ "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.",
26
23
  "",
24
+ `Pass ${WIDGET_TYPE_PARAM} and nothing else.`,
25
+ "",
26
+ "Widget types:",
27
27
  ];
28
- if (widgets.length === 0) {
29
- lines.push("No widget types are enabled on this deployment.");
30
- return lines.join("\n");
31
- }
32
- lines.push("Widget types:");
33
28
  for (const widget of widgets) {
34
29
  lines.push(`- ${widget.widgetType}: ${widget.description}`);
35
- lines.push(" fields:");
36
- if (widget.fields.length === 0) {
37
- lines.push(" none — pass widget_type only");
38
- continue;
39
- }
40
- lines.push(...widget.fields.map(fieldLine));
30
+ lines.push(` when: ${widget.callWhen}`);
31
+ lines.push(` not this card: ${widget.notFor}`);
32
+ lines.push(" for example:");
33
+ lines.push(...widget.examples.map((example) => ` - ${example}`));
41
34
  }
42
35
  return lines.join("\n");
43
36
  }
@@ -45,60 +38,23 @@ export function buildShowWidgetDescription(registry) {
45
38
  * Declared JSON schema: one flat object, no unions at any depth.
46
39
  *
47
40
  * OpenClaw flattens top-level unions, Gemini flattens nested ones, and OpenAI
48
- * strict mode rejects a schema containing one anywhere — so a discriminated
49
- * union on `widget_type` would buy nothing. Only `widget_type` is required;
50
- * per-widget requiredness is enforced in `execute()`.
41
+ * strict mode rejects a schema containing one anywhere. `widget_type` is the
42
+ * only parameter, and it is required.
51
43
  */
52
44
  export function buildShowWidgetParameters(registry) {
53
45
  const widgets = registry.enabled();
54
46
  if (widgets.length === 0) {
55
47
  throw new Error("show_widget has no enabled widget types; do not register the tool");
56
48
  }
57
- const properties = {
58
- [WIDGET_TYPE_PARAM]: {
59
- type: "string",
60
- enum: widgets.map((w) => w.widgetType),
61
- description: "Which widget to render.",
62
- },
63
- };
64
- // Fields shared by several widget types collapse into one property, so the
65
- // shared property has to admit every owner's input: per-widget limits are
66
- // enforced in execute(), and a declared bound stricter than one owner's would
67
- // make the provider reject a call that execute() would have accepted.
68
- const owners = new Map();
69
- for (const widget of widgets) {
70
- for (const field of widget.fields) {
71
- if (field.name === WIDGET_TYPE_PARAM) {
72
- throw new Error(`show_widget: ${widget.widgetType} declares a field named "${WIDGET_TYPE_PARAM}", which is the discriminator`);
73
- }
74
- const entry = owners.get(field.name);
75
- if (entry) {
76
- entry.types.push(widget.widgetType);
77
- entry.fields.push(field);
78
- continue;
79
- }
80
- owners.set(field.name, { types: [widget.widgetType], fields: [field] });
81
- }
82
- }
83
- for (const [name, { types, fields }] of owners) {
84
- const valueTypes = [...new Set(fields.map((f) => f.type))];
85
- if (valueTypes.length > 1) {
86
- throw new Error(`show_widget: field "${name}" is declared as ${valueTypes.join(" and ")} by ${types.join(", ")}; one schema property cannot be both`);
87
- }
88
- const property = { type: valueTypes[0] };
89
- const bounds = fields.map((f) => f.maxLength);
90
- if (bounds.every((b) => b !== undefined)) {
91
- property.maxLength = Math.max(...bounds);
92
- }
93
- property.description =
94
- types.length === 1
95
- ? `${fields[0].description} Accepted by: ${types[0]}.`
96
- : fields.map((f, i) => `${types[i]}: ${f.description}`).join(" ");
97
- properties[name] = property;
98
- }
99
49
  return {
100
50
  type: "object",
101
- properties,
51
+ properties: {
52
+ [WIDGET_TYPE_PARAM]: {
53
+ type: "string",
54
+ enum: widgets.map((w) => w.widgetType),
55
+ description: "Which card to render.",
56
+ },
57
+ },
102
58
  required: [WIDGET_TYPE_PARAM],
103
59
  additionalProperties: false,
104
60
  };
@@ -134,76 +90,16 @@ function resolveWidget(registry, args) {
134
90
  return widget;
135
91
  }
136
92
  /**
137
- * Validate the remaining args against the widget's own field list. Every
138
- * problem is reported in one message so the model can fix them all in a single
139
- * retry instead of discovering them one call at a time.
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.
140
96
  */
141
- function validateFields(widget, args) {
142
- // Guarded fields are accepted as keys so the widget can answer them itself;
143
- // they are absent from the description and the declared schema.
144
- const guarded = widget.guardedFields ?? [];
145
- const allowed = new Set([
146
- WIDGET_TYPE_PARAM,
147
- ...widget.fields.map((f) => f.name),
148
- ...guarded.map((f) => f.name),
149
- ]);
150
- const problems = [];
151
- const offending = [];
152
- const unexpected = Object.keys(args).filter((key) => !allowed.has(key));
153
- if (unexpected.length > 0) {
154
- offending.push(...unexpected);
155
- // Guarded names are parseable but not on offer, so they stay out of this list.
156
- const offered = [WIDGET_TYPE_PARAM, ...widget.fields.map((f) => f.name)];
157
- problems.push(`unexpected fields: ${unexpected.join(", ")} (allowed: ${offered.join(", ")})`);
158
- }
159
- const missing = [];
160
- const invalid = [];
161
- const values = {};
162
- // A guarded field goes to the handler exactly as it arrived. Its answer is
163
- // "drop this field", which is the same for every value, so complaining about
164
- // the type or the length first would only buy a retry that corrects a field
165
- // the model then has to remove anyway.
166
- for (const field of guarded) {
167
- const value = Object.hasOwn(args, field.name) ? args[field.name] : undefined;
168
- if (value !== undefined && value !== null)
169
- values[field.name] = value;
170
- }
171
- for (const field of widget.fields) {
172
- // Own keys only: an inherited `reason`/`toString` must not read as a value
173
- // the caller passed, since the unexpected-key check above only sees own keys.
174
- const value = Object.hasOwn(args, field.name) ? args[field.name] : undefined;
175
- if (value === undefined || value === null) {
176
- if (field.required)
177
- missing.push(field.name);
178
- continue;
179
- }
180
- if (typeof value !== "string") {
181
- invalid.push(`${field.name} (must be a ${field.type})`);
182
- continue;
183
- }
184
- if (value.trim().length === 0) {
185
- invalid.push(`${field.name} (must be a non-empty ${field.type}; omit it instead)`);
186
- continue;
187
- }
188
- if (field.maxLength !== undefined && value.length > field.maxLength) {
189
- invalid.push(`${field.name} (${value.length} chars, limit is ${field.maxLength})`);
190
- continue;
191
- }
192
- values[field.name] = value;
193
- }
194
- if (missing.length > 0) {
195
- offending.push(...missing);
196
- problems.push(`missing required fields: ${missing.join(", ")}`);
197
- }
198
- if (invalid.length > 0) {
199
- offending.push(...invalid.map((entry) => entry.split(" ")[0]));
200
- problems.push(`invalid fields: ${invalid.join(", ")}`);
201
- }
202
- if (problems.length > 0) {
203
- throw new WidgetValidationError(`show_widget failed for ${WIDGET_TYPE_PARAM} "${widget.widgetType}": ${problems.join("; ")}. ` +
204
- "Fix the named fields and call show_widget again with the same widget_type.", widget.widgetType, offending);
205
- }
206
- return values;
97
+ function rejectExtraFields(widget, args) {
98
+ const unexpected = Object.keys(args).filter((key) => key !== WIDGET_TYPE_PARAM);
99
+ if (unexpected.length === 0)
100
+ return;
101
+ 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);
207
103
  }
208
104
  /**
209
105
  * Build the `show_widget` tool for one agent turn. `sessionId` comes from the
@@ -211,9 +107,8 @@ function validateFields(widget, args) {
211
107
  * result depends on it.
212
108
  */
213
109
  export function createShowWidgetTool(options) {
214
- const { registry, logger, sessionId, strategies } = options;
110
+ const { registry, logger, sessionId } = options;
215
111
  const session = sessionId ?? "(unknown)";
216
- const ctx = { strategies };
217
112
  return {
218
113
  name: SHOW_WIDGET_TOOL_NAME,
219
114
  description: buildShowWidgetDescription(registry),
@@ -222,8 +117,8 @@ export function createShowWidgetTool(options) {
222
117
  try {
223
118
  const args = toArgs(params);
224
119
  const widget = resolveWidget(registry, args);
225
- const values = validateFields(widget, args);
226
- const result = await widget.handler(values, ctx);
120
+ rejectExtraFields(widget, args);
121
+ const result = await widget.handler();
227
122
  logger?.info(`[senpi-widgets] widget shown | widget_type=${widget.widgetType} widget_version=${widget.widgetVersion} session=${session}`);
228
123
  return {
229
124
  content: [{ type: "text", text: result.text }],
@@ -234,11 +129,6 @@ export function createShowWidgetTool(options) {
234
129
  if (err instanceof WidgetValidationError) {
235
130
  logger?.warn(`[senpi-widgets] validation failed | widget_type=${err.widgetType} fields=${err.fields.join(",")} session=${session} | ${err.message}`);
236
131
  }
237
- else if (err instanceof WidgetLookupError) {
238
- // The args were never judged — this is a backend problem, and it is the
239
- // only signal that a card the user asked for could not be built.
240
- logger?.warn(`[senpi-widgets] lookup failed | widget_type=${err.widgetType} session=${session} | ${err.message} | cause=${err.cause instanceof Error ? err.cause.message : String(err.cause ?? "(none)")}`);
241
- }
242
132
  else {
243
133
  logger?.error?.(`[senpi-widgets] unhandled failure | session=${session} | ${err instanceof Error ? err.message : String(err)}`);
244
134
  }
@@ -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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"}
@@ -1,23 +1,11 @@
1
1
  /**
2
2
  * Widget spec types.
3
3
  *
4
- * A widget spec is the single source for one `widget_type`: the fields it
5
- * accepts, the text that teaches the model about it, and the handler that
6
- * builds the result. The `show_widget` tool descriptor (enum + description) is
7
- * generated from the spec list, so the two cannot drift.
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.
8
8
  */
9
- /** Field value kinds a widget may declare. Extend as new widgets need them. */
10
- export type WidgetFieldType = "string";
11
- export interface WidgetFieldSpec {
12
- readonly name: string;
13
- readonly type: WidgetFieldType;
14
- /** Enforced in `execute()`; the declared JSON schema keeps every field optional. */
15
- readonly required: boolean;
16
- /** One line, shown to the model in the generated tool description. */
17
- readonly description: string;
18
- /** Upper bound for string fields. */
19
- readonly maxLength?: number;
20
- }
21
9
  /** Rendered by the client. Always carries the three shared keys. */
22
10
  export interface WidgetPayload {
23
11
  readonly widget_type: string;
@@ -30,53 +18,27 @@ export interface WidgetResult {
30
18
  /** Short line for the agent — what happened and what not to do next. */
31
19
  readonly text: string;
32
20
  }
33
- /** One of the caller's strategies, as the backend reported it. */
34
- export interface StrategyMatch {
35
- readonly id: string;
36
- /** The address exactly as the backend spells it, not as the model typed it. */
37
- readonly walletAddress: string;
38
- /** Lifecycle status, e.g. "ACTIVE", "PAUSED", "CLOSED". */
39
- readonly status: string;
40
- readonly name: string;
41
- }
42
- export interface StrategyLookup {
43
- /**
44
- * `null` means the backend answered and no strategy of the caller's holds that
45
- * address. A backend that did not answer usably **throws** — the two must never
46
- * collapse, or one timeout turns a good address into "not yours".
47
- */
48
- findByWallet(wallet: string): Promise<StrategyMatch | null>;
49
- }
50
- /** Everything a handler may reach for beyond its own args. */
51
- export interface WidgetContext {
52
- /** Absent when the plugin registered the tool without a backend. */
53
- readonly strategies?: StrategyLookup;
54
- }
55
- /**
56
- * A field a widget always refuses but wants to diagnose itself, because another
57
- * widget type declares it and the model can misroute it here.
58
- *
59
- * Matched by name only. No type or length check is applied, and the value
60
- * reaches the handler exactly as it arrived: the widget's answer is "drop this
61
- * field", which does not change with the value, and a type complaint would send
62
- * the model back to correct a field it should be removing.
63
- */
64
- export interface GuardedFieldSpec {
65
- readonly name: string;
66
- /** Why it is refused. For readers of the spec; the model sees the widget's own error. */
67
- readonly description: string;
68
- }
69
21
  export interface WidgetSpec {
70
22
  readonly widgetType: string;
71
23
  /** Bumped when the payload shape changes; the client falls back on unknown versions. */
72
24
  readonly widgetVersion: number;
73
- /** When to use this widget. Reproduced verbatim in the tool description. */
25
+ /** What the card does. Reproduced verbatim in the tool description. */
74
26
  readonly description: string;
75
- readonly fields: readonly WidgetFieldSpec[];
76
- /** Never advertised in the description or the declared schema. */
77
- readonly guardedFields?: readonly GuardedFieldSpec[];
78
- /** Receives args validated against `fields`, plus any guarded field verbatim. */
79
- readonly handler: (args: Readonly<Record<string, unknown>>, ctx: WidgetContext) => WidgetResult | Promise<WidgetResult>;
27
+ /**
28
+ * The condition that makes the model call the tool, stated as an intent it
29
+ * already has rather than a box to tick. Reproduced verbatim.
30
+ */
31
+ readonly callWhen: string;
32
+ /**
33
+ * The nearest thing this card is not, and the tool that owns it. One line,
34
+ * reproduced verbatim — a card can be mistaken for a neighbouring flow long
35
+ * before it is mistaken for an unrelated one.
36
+ */
37
+ readonly notFor: string;
38
+ /** Situations illustrating the condition. One line each, reproduced verbatim. */
39
+ readonly examples: readonly string[];
40
+ /** Takes no arguments: `show_widget` accepts `widget_type` and nothing else. */
41
+ readonly handler: () => WidgetResult | Promise<WidgetResult>;
80
42
  }
81
43
  /** A spec plus its resolved on/off state from plugin config. */
82
44
  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,+EAA+E;AAC/E,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;AAEvC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,qCAAqC;IACrC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,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,kEAAkE;AAClE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,+EAA+E;IAC/E,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;CAC7D;AAED,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,QAAQ,CAAC,UAAU,CAAC,EAAE,cAAc,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,kEAAkE;IAClE,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACrD,iFAAiF;IACjF,QAAQ,CAAC,OAAO,EAAE,CAChB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACvC,GAAG,EAAE,aAAa,KACf,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"}
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,10 +1,10 @@
1
1
  /**
2
2
  * Widget spec types.
3
3
  *
4
- * A widget spec is the single source for one `widget_type`: the fields it
5
- * accepts, the text that teaches the model about it, and the handler that
6
- * builds the result. The `show_widget` tool descriptor (enum + description) is
7
- * generated from the spec list, so the two cannot drift.
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.
8
8
  */
9
9
  export {};
10
10
  //# sourceMappingURL=types.js.map
@@ -3,11 +3,10 @@ import type { WidgetSpec } from "../types.js";
3
3
  * `fund_user_wallet` — a card that opens the client's existing deposit modal
4
4
  * for the user's own Senpi (Privy self-custody) wallet.
5
5
  *
6
- * The input surface is deliberately empty apart from a context sentence: the
7
- * modal resolves the wallet address and the networks from the user's own
8
- * session, so no amount, address or wallet id ever travels through the chat.
9
- * Nothing is authorized by showing the card, so there is no request id, no TTL
10
- * and no lifecycle.
6
+ * It takes no input: the modal resolves the wallet address and the networks
7
+ * from the user's own session, so no amount, address or wallet id travels
8
+ * through the chat. Showing the card authorizes nothing, so there is no
9
+ * request id, no TTL and no lifecycle.
11
10
  */
12
11
  export declare const fundUserWalletSpec: WidgetSpec;
13
12
  //# sourceMappingURL=fund-user-wallet.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fund-user-wallet.d.ts","sourceRoot":"","sources":["../../../src/widgets/widgets/fund-user-wallet.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAiB,UAAU,EAAE,MAAM,aAAa,CAAC;AAoC7D;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,EAAE,UAqChC,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,UA6BhC,CAAC"}
@@ -1,78 +1,38 @@
1
- import { WidgetValidationError } from "../errors.js";
2
- import { isWalletAddress } from "../strategy-lookup.js";
3
1
  const WIDGET_TYPE = "fund_user_wallet";
4
- /**
5
- * An address never belongs on this widget: the deposit modal resolves the
6
- * user's own wallet from their session. The call is refused whatever the value
7
- * is — the lookup only decides which correction the model is given, and a
8
- * lookup that fails still leaves the refusal correct, so it is never a reason
9
- * to accept.
10
- */
11
- async function refuseValue(value, ctx) {
12
- // Only an actual address can name a strategy, so anything else is refused
13
- // without spending an MCP round trip on a value that cannot match.
14
- const wallet = typeof value === "string" ? value.trim() : "";
15
- let match = null;
16
- if (isWalletAddress(wallet)) {
17
- try {
18
- match = (await ctx.strategies?.findByWallet(wallet)) ?? null;
19
- }
20
- catch {
21
- // Unverified reads as unknown; the "remove the field" correction still holds.
22
- }
23
- }
24
- throw new WidgetValidationError(match
25
- ? `show_widget failed for widget_type "${WIDGET_TYPE}": ${wallet} is the wallet of your strategy ` +
26
- `"${match.name.trim() || match.id}", not the user's own wallet. Call show_widget again with ` +
27
- 'widget_type "fund_strategy_wallet" and that address.'
28
- : `show_widget failed for widget_type "${WIDGET_TYPE}": it takes no address — the card resolves the ` +
29
- "user's own wallet from their session. Remove strategy_wallet and call again. To fund a strategy " +
30
- 'instead, use widget_type "fund_strategy_wallet".', WIDGET_TYPE, ["strategy_wallet"]);
31
- }
2
+ const WIDGET_VERSION = 1;
32
3
  /**
33
4
  * `fund_user_wallet` — a card that opens the client's existing deposit modal
34
5
  * for the user's own Senpi (Privy self-custody) wallet.
35
6
  *
36
- * The input surface is deliberately empty apart from a context sentence: the
37
- * modal resolves the wallet address and the networks from the user's own
38
- * session, so no amount, address or wallet id ever travels through the chat.
39
- * Nothing is authorized by showing the card, so there is no request id, no TTL
40
- * and no lifecycle.
7
+ * It takes no input: the modal resolves the wallet address and the networks
8
+ * from the user's own session, so no amount, address or wallet id travels
9
+ * through the chat. Showing the card authorizes nothing, so there is no
10
+ * request id, no TTL and no lifecycle.
41
11
  */
42
12
  export const fundUserWalletSpec = {
43
- widgetType: "fund_user_wallet",
44
- widgetVersion: 1,
45
- description: "Show the user a card that opens Senpi's deposit flow for their own wallet. " +
46
- "Use it when the user has no funds, cannot trade for lack of balance, or asks how to add money. " +
47
- "The card owns the address, the networks and the deposit copy — never restate them yourself.",
48
- fields: [
49
- {
50
- name: "reason",
51
- type: "string",
52
- required: false,
53
- description: "One plain sentence on why you are showing the card, e.g. \"Your wallet has no balance yet.\" " +
54
- "Recorded with the call; the card renders its own copy, so this is not displayed to the user.",
55
- maxLength: 280,
56
- },
13
+ widgetType: WIDGET_TYPE,
14
+ widgetVersion: WIDGET_VERSION,
15
+ description: "Opens Senpi's deposit flow for the user's OWN Senpi wallet, the one they deposit into from outside. " +
16
+ "The card owns the address, the networks and the deposit copy — never write a deposit address, a QR code " +
17
+ "or a network list in chat.",
18
+ callWhen: "Call it whenever you want money to arrive in the user's own Senpi wallet, whether or not the user " +
19
+ "mentions a deposit or a card.",
20
+ notFor: "Funding, topping up or adding margin to a STRATEGY — a strategy is funded from the user's own wallet " +
21
+ "by the strategy_top_up tool, never by depositing to an address.",
22
+ examples: [
23
+ "the user asks how to deposit into Senpi, or how to add funds to their own wallet",
24
+ "the user's own Senpi wallet is empty",
25
+ "that wallet has some balance, but not enough for the trade or position the user asked for",
26
+ "you are about to tell the user they need more money in their own wallet before you can act",
57
27
  ],
58
- guardedFields: [
59
- {
60
- name: "strategy_wallet",
61
- description: "Always refused here; guarded so the misrouted call gets a targeted correction.",
28
+ handler: () => ({
29
+ payload: {
30
+ widget_type: WIDGET_TYPE,
31
+ widget_version: WIDGET_VERSION,
32
+ status: "shown",
62
33
  },
63
- ],
64
- handler: async (args, ctx) => {
65
- if (Object.hasOwn(args, "strategy_wallet"))
66
- await refuseValue(args.strategy_wallet, ctx);
67
- return {
68
- payload: {
69
- widget_type: WIDGET_TYPE,
70
- widget_version: 1,
71
- status: "shown",
72
- },
73
- text: "Funding card shown. The user can deposit from the card. " +
74
- "Do not show it again in this turn; answer follow-up questions in text.",
75
- };
76
- },
34
+ text: "Funding card shown. The user can deposit from the card. " +
35
+ "Do not show it again in this turn; answer follow-up questions in text.",
36
+ }),
77
37
  };
78
38
  //# sourceMappingURL=fund-user-wallet.js.map