@openhands/extensions 0.4.2 → 0.6.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.
Files changed (134) hide show
  1. package/.github/workflows/pypi-publish.yml +104 -0
  2. package/.github/workflows/tests.yml +6 -0
  3. package/.release-please-manifest.json +1 -1
  4. package/AGENTS.md +1 -1
  5. package/README.md +31 -3
  6. package/automations/catalog/slack-channel-monitor.json +2 -2
  7. package/integrations/README.md +17 -7
  8. package/integrations/catalog/airtable.json +40 -10
  9. package/integrations/catalog/apify.json +0 -2
  10. package/integrations/catalog/asana.json +38 -0
  11. package/integrations/catalog/atlassian.json +5 -8
  12. package/integrations/catalog/bitbucket.json +39 -0
  13. package/integrations/catalog/box.json +39 -0
  14. package/integrations/catalog/brave-search.json +1 -2
  15. package/integrations/catalog/browser-mcp.json +0 -3
  16. package/integrations/catalog/canva.json +35 -0
  17. package/integrations/catalog/clickhouse.json +1 -2
  18. package/integrations/catalog/clickup.json +36 -0
  19. package/integrations/catalog/cloudflare-bindings.json +5 -8
  20. package/integrations/catalog/cloudflare-browser-rendering.json +5 -8
  21. package/integrations/catalog/cloudflare-builds.json +6 -9
  22. package/integrations/catalog/cloudflare-docs.json +4 -7
  23. package/integrations/catalog/cloudflare-observability.json +5 -8
  24. package/integrations/catalog/confluence.json +38 -0
  25. package/integrations/catalog/datadog.json +34 -0
  26. package/integrations/catalog/deepwiki.json +3 -7
  27. package/integrations/catalog/discord.json +39 -0
  28. package/integrations/catalog/dropbox.json +38 -0
  29. package/integrations/catalog/elevenlabs.json +27 -28
  30. package/integrations/catalog/everything.json +0 -2
  31. package/integrations/catalog/exa.json +0 -2
  32. package/integrations/catalog/fetch.json +0 -2
  33. package/integrations/catalog/figma.json +41 -9
  34. package/integrations/catalog/filesystem.json +0 -3
  35. package/integrations/catalog/firecrawl.json +0 -2
  36. package/integrations/catalog/freshdesk.json +38 -0
  37. package/integrations/catalog/git.json +0 -3
  38. package/integrations/catalog/github.json +51 -34
  39. package/integrations/catalog/gitlab.json +38 -0
  40. package/integrations/catalog/gmail.json +38 -0
  41. package/integrations/catalog/google-calendar.json +38 -0
  42. package/integrations/catalog/google-docs.json +38 -0
  43. package/integrations/catalog/google-drive.json +38 -0
  44. package/integrations/catalog/google-sheets.json +38 -0
  45. package/integrations/catalog/hubspot.json +34 -0
  46. package/integrations/catalog/huggingface.json +1 -2
  47. package/integrations/catalog/intercom.json +39 -0
  48. package/integrations/catalog/jira.json +38 -0
  49. package/integrations/catalog/kagi.json +2 -3
  50. package/integrations/catalog/linear.json +47 -16
  51. package/integrations/catalog/mailchimp.json +38 -0
  52. package/integrations/catalog/memory.json +0 -2
  53. package/integrations/catalog/microsoft-outlook.json +38 -0
  54. package/integrations/catalog/microsoft-teams.json +38 -0
  55. package/integrations/catalog/miro.json +38 -0
  56. package/integrations/catalog/monday.json +38 -0
  57. package/integrations/catalog/mongodb.json +1 -2
  58. package/integrations/catalog/neon.json +0 -2
  59. package/integrations/catalog/netlify.json +38 -0
  60. package/integrations/catalog/notion.json +37 -10
  61. package/integrations/catalog/obsidian.json +1 -3
  62. package/integrations/catalog/okta.json +38 -0
  63. package/integrations/catalog/onedrive.json +38 -0
  64. package/integrations/catalog/ordinal.json +33 -0
  65. package/integrations/catalog/paypal.json +5 -8
  66. package/integrations/catalog/pipedrive.json +39 -0
  67. package/integrations/catalog/plaid.json +31 -0
  68. package/integrations/catalog/playwright.json +0 -2
  69. package/integrations/catalog/posthog.json +38 -0
  70. package/integrations/catalog/quickbooks.json +38 -0
  71. package/integrations/catalog/redis.json +1 -3
  72. package/integrations/catalog/resend.json +1 -2
  73. package/integrations/catalog/salesforce.json +38 -0
  74. package/integrations/catalog/sentry.json +52 -14
  75. package/integrations/catalog/sequential-thinking.json +0 -2
  76. package/integrations/catalog/servicenow.json +39 -0
  77. package/integrations/catalog/sharepoint.json +38 -0
  78. package/integrations/catalog/shopify.json +38 -0
  79. package/integrations/catalog/slack.json +49 -10
  80. package/integrations/catalog/stripe.json +44 -14
  81. package/integrations/catalog/supabase.json +36 -9
  82. package/integrations/catalog/tavily.json +0 -2
  83. package/integrations/catalog/time.json +0 -2
  84. package/integrations/catalog/trello.json +31 -0
  85. package/integrations/catalog/vercel.json +38 -0
  86. package/integrations/catalog/webflow.json +34 -0
  87. package/integrations/catalog/xero.json +38 -0
  88. package/integrations/catalog/zendesk.json +38 -0
  89. package/integrations/catalog/zoom.json +38 -0
  90. package/integrations/catalog-index.js +171 -0
  91. package/integrations/index.d.ts +26 -60
  92. package/integrations/index.js +29 -207
  93. package/marketplaces/openhands-extensions.json +14 -1
  94. package/package.json +4 -7
  95. package/plugins/cobol-modernization/README.md +3 -3
  96. package/plugins/cobol-modernization/skills/{cobol-modernization-overview → cobol-modernization}/SKILL.md +1 -1
  97. package/plugins/magic-test/skills/magic-word/SKILL.md +1 -0
  98. package/plugins/migration-scoring/README.md +1 -1
  99. package/pyproject.toml +17 -3
  100. package/python/openhands_extensions/__init__.py +24 -0
  101. package/python/openhands_extensions/_version.py +24 -0
  102. package/python/openhands_extensions/integrations.py +92 -0
  103. package/release-please-config.json +2 -1
  104. package/scripts/build-integration-catalog.mjs +45 -0
  105. package/skills/agent-canvas-environment/.plugin/plugin.json +19 -0
  106. package/skills/agent-canvas-environment/README.md +5 -0
  107. package/skills/agent-canvas-environment/SKILL.md +141 -0
  108. package/skills/github-pr-reviewer/references/state-schema.md +18 -4
  109. package/skills/github-pr-reviewer/scripts/main.py +66 -12
  110. package/skills/github-repo-monitor/references/state-schema.md +11 -4
  111. package/skills/github-repo-monitor/scripts/main.py +67 -19
  112. package/skills/github-repo-monitor/tests/test_main.py +67 -8
  113. package/skills/index.js +19 -5
  114. package/skills/openhands-api/README.md +5 -1
  115. package/skills/openhands-api/SKILL.md +74 -5
  116. package/skills/openhands-automation/SKILL.md +3 -1
  117. package/skills/openhands-automation/references/custom-automation.md +166 -0
  118. package/skills/openhands-sdk/SKILL.md +8 -2
  119. package/skills/slack-channel-monitor/README.md +9 -5
  120. package/skills/slack-channel-monitor/SKILL.md +16 -6
  121. package/skills/slack-channel-monitor/references/slack-api.md +5 -3
  122. package/skills/slack-channel-monitor/references/state-schema.md +70 -36
  123. package/skills/slack-channel-monitor/scripts/main.py +335 -63
  124. package/tests/test_catalogs.py +21 -3
  125. package/tests/test_integration_catalog_in_sync.py +204 -0
  126. package/tests/test_slack_channel_monitor.py +142 -0
  127. package/tests/test_version_alignment.py +64 -0
  128. package/integrations/logos.d.ts +0 -5
  129. package/integrations/logos.js +0 -94
  130. package/integrations/oauth-provider-catalog.js +0 -553
  131. package/integrations/oauth-provider-registration-defaults.js +0 -610
  132. /package/plugins/cobol-modernization/skills/{mainfraime-removal → mainframe-removal}/SKILL.md +0 -0
  133. /package/plugins/cobol-modernization/skills/{mainfraime-removal → mainframe-removal}/references/cics-transformation-examples.md +0 -0
  134. /package/plugins/migration-scoring/skills/{migration-scoring-overview → migration-scoring}/SKILL.md +0 -0
@@ -1,12 +1,19 @@
1
- # State File Schema
1
+ # State Schema
2
2
 
3
- The automation maintains a JSON state file that persists across polling runs.
4
- This file is the source of truth for which conversations are active, which
3
+ The automation maintains a JSON state document that persists across polling runs.
4
+ This document is the source of truth for which conversations are active, which
5
5
  timestamps have been processed, and which messages were posted by the bot.
6
6
 
7
7
  ---
8
8
 
9
- ## File Location
9
+ ## Storage
10
+
11
+ **Primary (cloud):** The state is stored in the automation service's built-in KV
12
+ store under the key `"state"`. The KV store is available when `AUTOMATION_KV_TOKEN`
13
+ is injected into the run environment. Each automation has its own isolated namespace.
14
+
15
+ **Fallback (local/dev):** When the KV store is not available, the state is written
16
+ to a local JSON file at:
10
17
 
11
18
  ```
12
19
  {WORKSPACE_BASE_ROOT}/automation-state/slack_poller_{automation_id}.json
@@ -52,7 +59,7 @@ variable (field `automation_id`).
52
59
 
53
60
  ## `conversations` Map
54
61
 
55
- Key: `"{channel_id}:{thread_root_ts}"` - uniquely identifies a Slack thread.
62
+ Key: `"{channel_id}:{thread_root_ts}"` - uniquely identifies a Slack thread.
56
63
 
57
64
  Value: **ConversationRecord**
58
65
 
@@ -61,14 +68,25 @@ Value: **ConversationRecord**
61
68
  // Required fields
62
69
  "conversation_id": "550e8400-e29b-41d4-a716-446655440000",
63
70
  // OpenHands conversation UUID
64
- "channel_id": "C0123456789", // Slack channel ID
71
+ "channel_id": "C0123456789", // Slack channel ID
65
72
  "thread_ts": "1716576000.000100",
66
73
  // Slack thread root timestamp
67
74
  // (= msg_ts for top-level trigger messages)
68
- "status": "active", // "active" | "closed"
69
- "last_activity": 1716576060.0, // float Unix timestamp of the last time the
70
- // script sent a message to this conversation
71
- // (creation time, or time a reply was forwarded)
75
+ "status": "active", // "active" | "watching" | "closed"
76
+ "last_activity": 1716576060.0, // float Unix timestamp of the last time the
77
+ // script created, resumed, or summarized the
78
+ // OpenHands conversation
79
+
80
+ // Follow-up polling fields
81
+ "last_seen_reply_ts": "1716576000.000100",
82
+ // newest Slack reply ts observed for this thread
83
+ "reply_poll_backoff_seconds": 5, // current per-thread conversations.replies backoff
84
+ "next_reply_poll_at": 1716576065.0,// next Unix timestamp when replies may be polled
85
+ "watch_until": 1716576360.0, // follow-up watch expiry for completed conversations
86
+
87
+ // Present after expiry
88
+ "closed_reason": "followup_watch_expired",
89
+ "closed_at": 1716576360.0
72
90
  }
73
91
  ```
74
92
 
@@ -76,13 +94,13 @@ Value: **ConversationRecord**
76
94
 
77
95
  | Value | Meaning |
78
96
  |-------|---------|
79
- | `active` | Conversation is running or awaiting more input; replies will be forwarded |
80
- | `closed` | Summary has been posted to Slack; no further processing |
97
+ | `active` | Conversation is running or awaiting completion; triggered replies are forwarded to it |
98
+ | `watching` | A summary has been posted and the thread remains open briefly for triggered follow-ups |
99
+ | `closed` | The follow-up watch expired; future triggered replies create a new conversation |
81
100
 
82
- Closed conversations are retained in the map indefinitely (the map stays small
83
- since there are < 10 channels and the trigger rate is typically low). If the
84
- map grows unexpectedly, closed entries older than a configurable TTL can be
85
- pruned.
101
+ `watching` records use `watch_until` to avoid keeping every completed thread hot
102
+ forever. Quiet watched threads use exponential backoff for `conversations.replies`
103
+ polling, and each automation iteration polls at most one due thread.
86
104
 
87
105
  ---
88
106
 
@@ -109,9 +127,9 @@ exactly `now`, messages near the boundary are re-fetched on the next iteration.
109
127
  re-fetched messages from being processed twice (e.g., triggering a duplicate
110
128
  conversation or forwarding the same reply multiple times).
111
129
 
112
- Entries are added when a message is either skipped (not human, already handled)
113
- or successfully processed (trigger detected and conversation created, or reply
114
- forwarded).
130
+ Entries are added when a message is either skipped (not human, already handled,
131
+ or an untriggered reply in a watched thread) or successfully processed (trigger
132
+ detected and conversation created, or triggered reply forwarded).
115
133
 
116
134
  ---
117
135
 
@@ -119,25 +137,33 @@ forwarded).
119
137
 
120
138
  ```
121
139
  [trigger detected]
122
- │
123
- ▼
140
+ |
141
+ v
124
142
  status = "active"
125
143
  last_activity = now
126
- │
127
- (next run or later runs)
128
- │
129
- ┌─────┴──────────────────────────────────────────┐
130
- │ User sends a reply in the thread │
131
- │ → send_to_conversation() called │
132
- │ → last_activity = now │
133
- └─────────────────────────────────────────────────┘
134
- │
144
+ follow-up poll fields initialized
145
+ |
146
+ | triggered Slack reply while active
147
+ | -> send_to_conversation()
148
+ | -> last_activity = now
149
+ | -> watch window/backoff reset
150
+ |
135
151
  (when time.time() - last_activity > DONE_DEBOUNCE
136
- AND conversation_status ∈ {idle, finished, error, stuck})
137
- │
138
- ▼
152
+ AND conversation_status in {idle, finished, error, stuck})
153
+ |
154
+ v
139
155
  Post summary to Slack thread
156
+ status = "watching"
157
+ watch_until = now + THREAD_FOLLOWUP_WATCH_SECONDS
158
+ |
159
+ | triggered Slack reply before watch_until
160
+ | -> send_to_conversation()
161
+ | -> status = "active"
162
+ |
163
+ | no triggered reply before watch_until
164
+ v
140
165
  status = "closed"
166
+ closed_reason = "followup_watch_expired"
141
167
  ```
142
168
 
143
169
  ---
@@ -158,14 +184,22 @@ forwarded).
158
184
  "channel_id": "C0123456789",
159
185
  "thread_ts": "1716575900.000100",
160
186
  "status": "active",
161
- "last_activity": 1716575902.3
187
+ "last_activity": 1716575902.3,
188
+ "last_seen_reply_ts": "1716575900.000100",
189
+ "reply_poll_backoff_seconds": 5,
190
+ "next_reply_poll_at": 1716575907.3,
191
+ "watch_until": 1716576202.3
162
192
  },
163
193
  "C9876543210:1716570000.000500": {
164
194
  "conversation_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
165
195
  "channel_id": "C9876543210",
166
196
  "thread_ts": "1716570000.000500",
167
- "status": "closed",
168
- "last_activity": 1716572100.0
197
+ "status": "watching",
198
+ "last_activity": 1716572100.0,
199
+ "last_seen_reply_ts": "1716572050.000100",
200
+ "reply_poll_backoff_seconds": 20,
201
+ "next_reply_poll_at": 1716572120.0,
202
+ "watch_until": 1716572400.0
169
203
  }
170
204
  },
171
205
  "bot_message_ts": [