@openhands/extensions 0.26.0 → 0.27.0

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.
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.26.0"
2
+ ".": "0.27.0"
3
3
  }
@@ -270,12 +270,13 @@ falling back to its built-in defaults when the manifest is absent or fails admis
270
270
  captions it: `overview.tiles[].metric` names a host-computed value (`automations`, `needs-attention`,
271
271
  `total-runs`, `average-duration`), filter option values name host predicates (`status`: enabled /
272
272
  latest-run-failed / disabled; `trigger`: `event` matches event-triggered automations, `schedule`
273
- everything else), `sort` values name host comparators, and `insights` captions the host's run-health
274
- states and per-automation stats. The health precedence, the run sampling, the value formatting, the
275
- relative-time rendering, and the filtered-empty state with its reset button are the host's - a manifest
276
- cannot redefine them, only relabel what appears. Tile `detail` copy is plain substitution over the
277
- metric's placeholder namespace (only the `automations` metric exposes `{{active}}`); `zeroDetail`
278
- replaces `detail` while the value is zero.
273
+ everything else; `created_by`: `me` matches automations the signed-in user created, `others` everything
274
+ else, and the host decides where it is shown), `sort` values name host comparators, and `insights`
275
+ captions the host's run-health states and per-automation stats. The health precedence, the run
276
+ sampling, the value formatting, the relative-time rendering, and the filtered-empty state with its reset
277
+ button are the host's - a manifest cannot redefine them, only relabel what appears. Tile `detail` copy is
278
+ plain substitution over the metric's placeholder namespace (only the `automations` metric exposes
279
+ `{{active}}`); `zeroDetail` replaces `detail` while the value is zero.
279
280
  - **`docsUrl`** - the automations documentation link, prefix-pinned to docs.openhands.dev by schema.
280
281
  - **`attributes`** - the input surface of an existing Automation: which attributes can be set after
281
282
  creation, keyed by the runtime-model property the host sends (`name`, `prompt`, `model`, `timeout`,
@@ -309,6 +309,7 @@ export type AutomationStatusFilterValue =
309
309
  | "failing"
310
310
  | "disabled";
311
311
  export type AutomationTriggerFilterValue = "all" | "schedule" | "event";
312
+ export type AutomationCreatedByFilterValue = "all" | "me" | "others";
312
313
 
313
314
  /**
314
315
  * A filter dropdown. Values name predicates the host implements; the manifest
@@ -327,9 +328,16 @@ export interface AutomationTriggerFilter {
327
328
  options: { value: AutomationTriggerFilterValue; label: string }[];
328
329
  }
329
330
 
331
+ export interface AutomationCreatedByFilter {
332
+ id: "created_by";
333
+ label: string;
334
+ options: { value: AutomationCreatedByFilterValue; label: string }[];
335
+ }
336
+
330
337
  export type AutomationDashboardFilter =
331
338
  | AutomationStatusFilter
332
- | AutomationTriggerFilter;
339
+ | AutomationTriggerFilter
340
+ | AutomationCreatedByFilter;
333
341
 
334
342
  /** A comparator the host implements, named from a closed set. */
335
343
  export type AutomationSortValue = "last-run" | "runs" | "name";
@@ -71,6 +71,15 @@
71
71
  { "value": "schedule", "label": "Scheduled" },
72
72
  { "value": "event", "label": "Event-driven" }
73
73
  ]
74
+ },
75
+ {
76
+ "id": "created_by",
77
+ "label": "Filter by creator",
78
+ "options": [
79
+ { "value": "all", "label": "Anyone" },
80
+ { "value": "me", "label": "Me" },
81
+ { "value": "others", "label": "Others" }
82
+ ]
74
83
  }
75
84
  ],
76
85
  "sort": {
@@ -86,12 +86,13 @@
86
86
  "description": "The filter dropdowns of the list page, in render order. Each filter id may appear once; the host's admission checks that.",
87
87
  "type": "array",
88
88
  "minItems": 1,
89
- "maxItems": 2,
89
+ "maxItems": 3,
90
90
  "uniqueItems": true,
91
91
  "items": {
92
92
  "oneOf": [
93
93
  { "$ref": "#/$defs/statusFilter" },
94
- { "$ref": "#/$defs/triggerFilter" }
94
+ { "$ref": "#/$defs/triggerFilter" },
95
+ { "$ref": "#/$defs/createdByFilter" }
95
96
  ]
96
97
  }
97
98
  },
@@ -425,6 +426,40 @@
425
426
  }
426
427
  }
427
428
  },
429
+ "createdByFilter": {
430
+ "description": "The creator filter. Like the status filter, values name host-implemented predicates: me matches automations the signed-in user created, others every other automation. The host decides where the filter is shown and may hide it where every automation is the signed-in user's.",
431
+ "type": "object",
432
+ "additionalProperties": false,
433
+ "required": ["id", "label", "options"],
434
+ "properties": {
435
+ "id": { "const": "created_by" },
436
+ "label": {
437
+ "description": "The control's accessible name.",
438
+ "$ref": "#/$defs/copy"
439
+ },
440
+ "options": {
441
+ "description": "Each value may appear once; the host's admission checks that.",
442
+ "type": "array",
443
+ "minItems": 2,
444
+ "maxItems": 8,
445
+ "uniqueItems": true,
446
+ "items": {
447
+ "type": "object",
448
+ "additionalProperties": false,
449
+ "required": ["value", "label"],
450
+ "properties": {
451
+ "value": { "enum": ["all", "me", "others"] },
452
+ "label": { "$ref": "#/$defs/copy" }
453
+ }
454
+ },
455
+ "contains": {
456
+ "type": "object",
457
+ "required": ["value"],
458
+ "properties": { "value": { "const": "all" } }
459
+ }
460
+ }
461
+ }
462
+ },
428
463
  "sort": {
429
464
  "description": "The sort dropdown. Values name comparators the host implements. default must be one of the declared option values; the host's admission checks that, as schemas cannot cheaply.",
430
465
  "type": "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openhands/extensions",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "Public OpenHands extension catalogs for skills, plugins, integrations, and automation templates.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "openhands-extensions"
3
- version = "0.26.0"
3
+ version = "0.27.0"
4
4
  description = "OpenHands extensions, plugins, and skills (Python bindings for the integration catalog)"
5
5
  requires-python = ">=3.12"
6
6
  dependencies = [
@@ -18,7 +18,7 @@ from importlib.metadata import PackageNotFoundError, version
18
18
  #: Kept in lock-step with pyproject.toml/package.json by the version test.
19
19
  #: release-please only rewrites a semver found on the annotated line itself, so
20
20
  #: the annotation must stay on the assignment; on its own line it is a no-op.
21
- _FALLBACK_VERSION = "0.26.0" # x-release-please-version
21
+ _FALLBACK_VERSION = "0.27.0" # x-release-please-version
22
22
 
23
23
  try:
24
24
  __version__: str = version("openhands-extensions")
@@ -30,6 +30,12 @@ def _with(mutation):
30
30
  return document
31
31
 
32
32
 
33
+ def _filter(document, filter_id):
34
+ return next(
35
+ f for f in document["pages"]["list"]["filters"] if f["id"] == filter_id
36
+ )
37
+
38
+
33
39
  def test_schema_is_a_valid_draft_2020_12_schema():
34
40
  jsonschema.Draft202012Validator.check_schema(SCHEMA)
35
41
 
@@ -94,7 +100,23 @@ def test_featured_automations_resolve_to_catalog_entries():
94
100
  ),
95
101
  (
96
102
  "a status filter without the all option",
97
- lambda doc: doc["pages"]["list"]["filters"][0]["options"].pop(0),
103
+ lambda doc: _filter(doc, "status")["options"].pop(0),
104
+ ),
105
+ (
106
+ "a creator filter without the all option",
107
+ lambda doc: _filter(doc, "created_by")["options"].pop(0),
108
+ ),
109
+ (
110
+ "a creator filter value the host does not implement",
111
+ lambda doc: _filter(doc, "created_by")["options"].append(
112
+ {"value": "team", "label": "My team"}
113
+ ),
114
+ ),
115
+ (
116
+ "more filters than the host renders",
117
+ lambda doc: doc["pages"]["list"]["filters"].append(
118
+ {**doc["pages"]["list"]["filters"][0], "label": "Filter again"}
119
+ ),
98
120
  ),
99
121
  ],
100
122
  )