terse-sdk 0.1.0__tar.gz

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 (35) hide show
  1. terse_sdk-0.1.0/.gitignore +30 -0
  2. terse_sdk-0.1.0/PKG-INFO +135 -0
  3. terse_sdk-0.1.0/README.md +113 -0
  4. terse_sdk-0.1.0/pyproject.toml +34 -0
  5. terse_sdk-0.1.0/shared/ApiRoutes.ts +350 -0
  6. terse_sdk-0.1.0/shared/ApprovalTypes.ts +36 -0
  7. terse_sdk-0.1.0/shared/ClientBoundTools.ts +78 -0
  8. terse_sdk-0.1.0/shared/Configs.ts +874 -0
  9. terse_sdk-0.1.0/shared/DonatedState.ts +14 -0
  10. terse_sdk-0.1.0/shared/Entities.ts +7 -0
  11. terse_sdk-0.1.0/shared/FrontendRoutes.ts +56 -0
  12. terse_sdk-0.1.0/shared/Integrations.ts +291 -0
  13. terse_sdk-0.1.0/shared/InvalidationKeys.ts +218 -0
  14. terse_sdk-0.1.0/shared/ModelEvents.ts +89 -0
  15. terse_sdk-0.1.0/shared/Notifications.ts +49 -0
  16. terse_sdk-0.1.0/shared/RunHistoryTypes.ts +123 -0
  17. terse_sdk-0.1.0/shared/SentNotifications.ts +32 -0
  18. terse_sdk-0.1.0/shared/SocketEvents.ts +57 -0
  19. terse_sdk-0.1.0/shared/Survey.ts +10 -0
  20. terse_sdk-0.1.0/shared/TicketSystem.ts +170 -0
  21. terse_sdk-0.1.0/shared/ToolDisplayUtils.ts +1089 -0
  22. terse_sdk-0.1.0/shared/ToolsTypes.ts +21 -0
  23. terse_sdk-0.1.0/shared/types.ts +884 -0
  24. terse_sdk-0.1.0/src/terse_sdk/__init__.py +103 -0
  25. terse_sdk-0.1.0/src/terse_sdk/generated/__init__.py +3 -0
  26. terse_sdk-0.1.0/src/terse_sdk/generated/_schema.json +2518 -0
  27. terse_sdk-0.1.0/src/terse_sdk/generated/models.py +1235 -0
  28. terse_sdk-0.1.0/src/terse_sdk/models/__init__.py +73 -0
  29. terse_sdk-0.1.0/src/terse_sdk/models/_base.py +12 -0
  30. terse_sdk-0.1.0/src/terse_sdk/models/config.py +11 -0
  31. terse_sdk-0.1.0/src/terse_sdk/models/events.py +187 -0
  32. terse_sdk-0.1.0/src/terse_sdk/models/jobs.py +30 -0
  33. terse_sdk-0.1.0/src/terse_sdk/py.typed +1 -0
  34. terse_sdk-0.1.0/src/terse_sdk/runtime.py +555 -0
  35. terse_sdk-0.1.0/tests/test_runtime.py +389 -0
@@ -0,0 +1,30 @@
1
+ /node_modules
2
+ /backend/node_modules
3
+ /backend/dist
4
+ /packages/terse-sdk/node_modules
5
+ /packages/terse-sdk/dist
6
+ /packages/terse-sdk/src/shared
7
+ /packages/terse-cli/node_modules
8
+ /packages/terse-cli/dist
9
+ .pnpm-store/
10
+
11
+ # Python SDK artifacts
12
+ __pycache__/
13
+ *.py[cod]
14
+ .pytest_cache/
15
+ .mypy_cache/
16
+ .ruff_cache/
17
+ .tox/
18
+ .coverage
19
+ .coverage.*
20
+ htmlcov/
21
+ .venv/
22
+ venv/
23
+ *.egg-info/
24
+ pip-wheel-metadata/
25
+ /packages/terse-python-sdk/build/
26
+ /packages/terse-python-sdk/dist/
27
+ /packages/terse-python-sdk/shared/
28
+ /packages/terse-python-cli/build/
29
+ /packages/terse-python-cli/dist/
30
+ /packages/terse-python-cli/shared/
@@ -0,0 +1,135 @@
1
+ Metadata-Version: 2.4
2
+ Name: terse-sdk
3
+ Version: 0.1.0
4
+ Summary: Python SDK for building jobs on the Terse platform.
5
+ Project-URL: Homepage, https://useterse.ai
6
+ Author: Terse
7
+ Keywords: agents,ai,automation,sdk,terse
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Typing :: Typed
16
+ Requires-Python: >=3.11
17
+ Requires-Dist: httpx-sse<0.5,>=0.4
18
+ Requires-Dist: httpx>=0.28.1
19
+ Requires-Dist: pydantic-settings>=2.13.1
20
+ Requires-Dist: pydantic>=2.12.5
21
+ Description-Content-Type: text/markdown
22
+
23
+ # terse-sdk
24
+
25
+ Python SDK for building jobs on the [Terse](https://useterse.ai) platform.
26
+
27
+ Most users should start with `terse-cli`, which scaffolds a project and generates `terse_generated.py` helpers for the currently supported trigger and skill surface.
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ python -m pip install terse-sdk
33
+ ```
34
+
35
+ ## Runtime API
36
+
37
+ The SDK provides:
38
+
39
+ - `Terse` for runtime job registration
40
+ - `@app.job(...)` for declaring jobs
41
+ - `TerseAgent` for agent runs and deterministic tool execution
42
+ - typed event models such as `CronJobInputEvent`
43
+ - generated backend models under `terse_sdk.generated.models`
44
+
45
+ ## Quick Start
46
+
47
+ ```python
48
+ from terse_sdk import CronJobInputEvent, EventType, Terse, TerseAgent
49
+
50
+ app = Terse()
51
+
52
+ @app.job(
53
+ name="example-job",
54
+ triggers=[],
55
+ skills=[],
56
+ )
57
+ def example(event: CronJobInputEvent, agent: TerseAgent) -> None:
58
+ for stream_event in agent.run(
59
+ "Answer with one short, cute sentence about this cron job.",
60
+ event,
61
+ ):
62
+ if stream_event.type == EventType.FINAL_OUTPUT:
63
+ print(stream_event.finalOutput)
64
+
65
+ example(
66
+ CronJobInputEvent(
67
+ event_type="manual",
68
+ formatted_content="Manual local run",
69
+ debug_log="README example",
70
+ ),
71
+ TerseAgent(),
72
+ )
73
+ ```
74
+
75
+ That example is intentionally self-contained. In a real Terse project, trigger and skill configs normally come from the generated helpers in `terse_generated.py`, not from manually constructing low-level DTOs.
76
+
77
+ ## Generated Helpers
78
+
79
+ The SDK package does not generate project helpers by itself.
80
+
81
+ If you scaffold a project with `terse init` and then run `terse generate`, your project gets `src/terse_generated.py` with the currently supported helpers:
82
+
83
+ - `Schedule.cron(...)`
84
+ - `Attio.skill(...)`
85
+ - `Snowflake.skill(...)`
86
+ - deterministic wrappers on `agent.tools.attio` and `agent.tools.snowflake`
87
+
88
+ Example inside a generated project:
89
+
90
+ ```python
91
+ from terse_generated import Schedule, Snowflake, TerseAgent
92
+ from terse_sdk import CronJobInputEvent, Terse
93
+
94
+ app = Terse()
95
+
96
+ @app.job(
97
+ name="snowflake-job",
98
+ triggers=[Schedule.cron("0 9 * * 1")],
99
+ skills=[Snowflake.skill()],
100
+ )
101
+ def example(event: CronJobInputEvent, agent: TerseAgent) -> None:
102
+ result = agent.tools.snowflake.execute_query(query="select current_date()")
103
+ print(result)
104
+ ```
105
+
106
+ ## Environment Variables
107
+
108
+ - `TERSE_API_KEY`: required for agent runs and deterministic tool execution
109
+ - `TERSE_BACKEND_URL`: optional backend override for local development
110
+ - `TERSE_FRONTEND_URL`: optional frontend override for local development
111
+
112
+ ## Recommended Path
113
+
114
+ If you want the full project workflow, install the CLI instead:
115
+
116
+ ```bash
117
+ python -m pip install terse-cli
118
+ terse init my-terse-job
119
+ ```
120
+
121
+ ## Source
122
+
123
+ - Homepage: [useterse.ai](https://useterse.ai)
124
+ - Repository: [github.com/TerseAI/Terse](https://github.com/TerseAI/Terse)
125
+ - Issues: [github.com/TerseAI/Terse/issues](https://github.com/TerseAI/Terse/issues)
126
+
127
+ ## Development
128
+
129
+ If you are working on the SDK itself from the monorepo:
130
+
131
+ ```bash
132
+ npm run python:setup
133
+ npm run python:check
134
+ npm run python:build
135
+ ```
@@ -0,0 +1,113 @@
1
+ # terse-sdk
2
+
3
+ Python SDK for building jobs on the [Terse](https://useterse.ai) platform.
4
+
5
+ Most users should start with `terse-cli`, which scaffolds a project and generates `terse_generated.py` helpers for the currently supported trigger and skill surface.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ python -m pip install terse-sdk
11
+ ```
12
+
13
+ ## Runtime API
14
+
15
+ The SDK provides:
16
+
17
+ - `Terse` for runtime job registration
18
+ - `@app.job(...)` for declaring jobs
19
+ - `TerseAgent` for agent runs and deterministic tool execution
20
+ - typed event models such as `CronJobInputEvent`
21
+ - generated backend models under `terse_sdk.generated.models`
22
+
23
+ ## Quick Start
24
+
25
+ ```python
26
+ from terse_sdk import CronJobInputEvent, EventType, Terse, TerseAgent
27
+
28
+ app = Terse()
29
+
30
+ @app.job(
31
+ name="example-job",
32
+ triggers=[],
33
+ skills=[],
34
+ )
35
+ def example(event: CronJobInputEvent, agent: TerseAgent) -> None:
36
+ for stream_event in agent.run(
37
+ "Answer with one short, cute sentence about this cron job.",
38
+ event,
39
+ ):
40
+ if stream_event.type == EventType.FINAL_OUTPUT:
41
+ print(stream_event.finalOutput)
42
+
43
+ example(
44
+ CronJobInputEvent(
45
+ event_type="manual",
46
+ formatted_content="Manual local run",
47
+ debug_log="README example",
48
+ ),
49
+ TerseAgent(),
50
+ )
51
+ ```
52
+
53
+ That example is intentionally self-contained. In a real Terse project, trigger and skill configs normally come from the generated helpers in `terse_generated.py`, not from manually constructing low-level DTOs.
54
+
55
+ ## Generated Helpers
56
+
57
+ The SDK package does not generate project helpers by itself.
58
+
59
+ If you scaffold a project with `terse init` and then run `terse generate`, your project gets `src/terse_generated.py` with the currently supported helpers:
60
+
61
+ - `Schedule.cron(...)`
62
+ - `Attio.skill(...)`
63
+ - `Snowflake.skill(...)`
64
+ - deterministic wrappers on `agent.tools.attio` and `agent.tools.snowflake`
65
+
66
+ Example inside a generated project:
67
+
68
+ ```python
69
+ from terse_generated import Schedule, Snowflake, TerseAgent
70
+ from terse_sdk import CronJobInputEvent, Terse
71
+
72
+ app = Terse()
73
+
74
+ @app.job(
75
+ name="snowflake-job",
76
+ triggers=[Schedule.cron("0 9 * * 1")],
77
+ skills=[Snowflake.skill()],
78
+ )
79
+ def example(event: CronJobInputEvent, agent: TerseAgent) -> None:
80
+ result = agent.tools.snowflake.execute_query(query="select current_date()")
81
+ print(result)
82
+ ```
83
+
84
+ ## Environment Variables
85
+
86
+ - `TERSE_API_KEY`: required for agent runs and deterministic tool execution
87
+ - `TERSE_BACKEND_URL`: optional backend override for local development
88
+ - `TERSE_FRONTEND_URL`: optional frontend override for local development
89
+
90
+ ## Recommended Path
91
+
92
+ If you want the full project workflow, install the CLI instead:
93
+
94
+ ```bash
95
+ python -m pip install terse-cli
96
+ terse init my-terse-job
97
+ ```
98
+
99
+ ## Source
100
+
101
+ - Homepage: [useterse.ai](https://useterse.ai)
102
+ - Repository: [github.com/TerseAI/Terse](https://github.com/TerseAI/Terse)
103
+ - Issues: [github.com/TerseAI/Terse/issues](https://github.com/TerseAI/Terse/issues)
104
+
105
+ ## Development
106
+
107
+ If you are working on the SDK itself from the monorepo:
108
+
109
+ ```bash
110
+ npm run python:setup
111
+ npm run python:check
112
+ npm run python:build
113
+ ```
@@ -0,0 +1,34 @@
1
+ [project]
2
+ name = "terse-sdk"
3
+ version = "0.1.0"
4
+ description = "Python SDK for building jobs on the Terse platform."
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ authors = [{ name = "Terse" }]
8
+ keywords = ["terse", "ai", "agents", "automation", "sdk"]
9
+ classifiers = [
10
+ "Development Status :: 3 - Alpha",
11
+ "Intended Audience :: Developers",
12
+ "Programming Language :: Python :: 3",
13
+ "Programming Language :: Python :: 3.11",
14
+ "Programming Language :: Python :: 3.12",
15
+ "Programming Language :: Python :: 3.13",
16
+ "Typing :: Typed",
17
+ "Topic :: Software Development :: Libraries :: Python Modules",
18
+ ]
19
+ dependencies = [
20
+ "httpx>=0.28.1",
21
+ "httpx-sse>=0.4,<0.5",
22
+ "pydantic>=2.12.5",
23
+ "pydantic-settings>=2.13.1",
24
+ ]
25
+
26
+ [project.urls]
27
+ Homepage = "https://useterse.ai"
28
+
29
+ [build-system]
30
+ requires = ["hatchling>=1.29.0"]
31
+ build-backend = "hatchling.build"
32
+
33
+ [tool.hatch.build.targets.wheel]
34
+ packages = ["src/terse_sdk"]
@@ -0,0 +1,350 @@
1
+ /**
2
+ * API route path constants
3
+ *
4
+ * These constants standardize API route paths across frontend and backend,
5
+ * preventing magic strings and making refactoring easier.
6
+ *
7
+ * Dynamic routes use route objects with both Express patterns and URL builders
8
+ * to ensure frontend and backend stay in sync.
9
+ */
10
+
11
+ // Type definitions for route objects
12
+
13
+ export const ApiRoutes = {
14
+ // Authentication routes
15
+ AUTH: {
16
+ ME: "/me",
17
+ LOGIN: "/login",
18
+ LOGIN_URL: "/login/url",
19
+ LOGOUT: "/logout",
20
+ LOGOUT_URL: "/logout/url",
21
+ GITHUB_APP_CALLBACK: "/auth/github-app/callback",
22
+ WORKOS_CALLBACK: "/auth/workos/callback"
23
+ },
24
+
25
+ WORKOS: {
26
+ WIDGET_TOKEN: "/auth/workos/widget-token"
27
+ },
28
+
29
+ ORGANIZATIONS: {
30
+ CREATE: "/organizations",
31
+ GET_CURRENT: "/organizations/current",
32
+ LIST: "/organizations",
33
+ SWITCH: "/organizations/switch",
34
+ UPDATE: "/organizations",
35
+ LOGO_UPLOAD_URL: "/organizations/logo/upload-url",
36
+ LOGO: {
37
+ pattern: "/organizations/:organizationId/logo",
38
+ build: (organizationId: string) => `/organizations/${encodeURIComponent(organizationId)}/logo`,
39
+ params: { organizationId: "string" } as const
40
+ }
41
+ },
42
+
43
+ // Stats routes
44
+ STATS: "/stats",
45
+
46
+ // Run history routes
47
+ RUN_HISTORY: {
48
+ ALL: "/run-history",
49
+ ACTIONS: "/run-history/actions",
50
+ BY_AGENT_ID: {
51
+ pattern: "/run-history/:agentId",
52
+ build: (agentId: string) => `/run-history/${encodeURIComponent(agentId)}`,
53
+ params: { agentId: "string" } as const
54
+ },
55
+ CHAT_BY_RUN_ID: {
56
+ pattern: "/run-history/:runId/chat",
57
+ build: (runId: string) => `/run-history/${encodeURIComponent(runId)}/chat`,
58
+ params: { runId: "string" } as const
59
+ }
60
+ },
61
+
62
+ // Session routes
63
+ SESSION: {
64
+ TOKEN: "/session/token"
65
+ },
66
+
67
+ // GitHub routes
68
+ GITHUB: {
69
+ INTEGRATIONS: "/github/integrations",
70
+ INSTALLATION_URL: "/github/installation-url",
71
+ GET_REPOSITORIES_FOR_INTEGRATION: "/github/get-repositories-for-integration",
72
+ INSTALLATION_CALLBACK: "/github/installation-callback",
73
+ INSTALLATION_DELETED: "/github/installation-deleted",
74
+ UNIFIED_EVENT: "/github/unified-event"
75
+ },
76
+
77
+ // Atlassian/Jira routes
78
+ ATLASSIAN: {
79
+ INTEGRATIONS: "/atlassian/integrations",
80
+ OAUTH_CALLBACK: "/atlassian/oauth/callback"
81
+ },
82
+
83
+ JIRA: {
84
+ RESOURCES: "/jira/resources",
85
+ GET_API_KEY: "/jira/get-api-key",
86
+ SET_API_KEY: "/jira/set-api-key",
87
+ VALIDATE_AND_FETCH_PROJECTS: "/jira/validate-and-fetch-projects",
88
+ DELETE_CREDENTIALS: "/jira/delete-credentials"
89
+ },
90
+
91
+ // Confluence routes
92
+ CONFLUENCE: {
93
+ INTEGRATIONS: "/confluence/integrations",
94
+ RESOURCES: "/confluence/resources"
95
+ },
96
+
97
+ // Gmail routes
98
+ GMAIL: {
99
+ INTEGRATIONS: "/gmail/integrations",
100
+ CALLBACK: "/gmail/callback",
101
+ DELETE_INTEGRATION: "/gmail/delete-integration"
102
+ },
103
+
104
+ // Notion routes
105
+ NOTION: {
106
+ INTEGRATIONS: "/notion/integrations",
107
+ OAUTH_CALLBACK: "/notion/oauth/callback",
108
+ RESOURCES: "/notion/resources",
109
+ DELETE_INTEGRATION: "/notion/delete-integration"
110
+ },
111
+
112
+ // Figma routes
113
+ FIGMA: {
114
+ INTEGRATIONS: "/figma/integrations",
115
+ OAUTH_CALLBACK: "/figma/oauth/callback"
116
+ },
117
+
118
+ // Linear routes
119
+ LINEAR: {
120
+ OAUTH_CALLBACK: "/linear/oauth/callback",
121
+ WEBHOOK: "/linear/webhook",
122
+ INTEGRATIONS: "/linear/integrations",
123
+ TEAMS: "/linear/teams"
124
+ },
125
+
126
+ // Slack routes
127
+ SLACK: {
128
+ INTEGRATIONS: "/slack/integrations",
129
+ GET_CURRENT_INTEGRATION: "/slack/get-current-integration",
130
+ OAUTH_CALLBACK: "/slack/oauth-callback",
131
+ CHANNELS: "/slack/channels",
132
+ USERS: "/slack/users",
133
+ EVENTS: "/slack/events"
134
+ },
135
+
136
+ // Posthog routes
137
+ POSTHOG: {
138
+ INTEGRATIONS: "/posthog/integrations",
139
+ PROJECTS: "/posthog/projects"
140
+ },
141
+
142
+ // LaunchDarkly routes
143
+ LAUNCHDARKLY: {
144
+ INTEGRATIONS: "/launchdarkly/integrations",
145
+ PROJECTS_BY_INTEGRATION_ID: {
146
+ pattern: "/launchdarkly/integrations/:integrationId/projects",
147
+ build: (integrationId: string) => `/launchdarkly/integrations/${encodeURIComponent(integrationId)}/projects`,
148
+ params: { integrationId: "string" } as const
149
+ },
150
+ ENVIRONMENTS_BY_INTEGRATION_AND_PROJECT: {
151
+ pattern: "/launchdarkly/integrations/:integrationId/projects/:projectKey/environments",
152
+ build: (integrationId: string, projectKey: string) => `/launchdarkly/integrations/${encodeURIComponent(integrationId)}/projects/${encodeURIComponent(projectKey)}/environments`,
153
+ params: { integrationId: "string", projectKey: "string" } as const
154
+ }
155
+ },
156
+
157
+ // Datadog routes
158
+ DATADOG: {
159
+ INTEGRATIONS: "/datadog/integrations",
160
+ INDEXES: "/datadog/indexes"
161
+ },
162
+
163
+ // WorkOS Integration routes (customer's own WorkOS account)
164
+ WORKOS_INTEGRATION: {
165
+ INTEGRATIONS: "/workos-integration/integrations",
166
+ WEBHOOK_SECRET: "/workos-integration/webhook-secret"
167
+ },
168
+
169
+ // Snowflake routes
170
+ SNOWFLAKE: {
171
+ INTEGRATIONS: "/snowflake/integrations"
172
+ },
173
+
174
+ // Attio routes
175
+ ATTIO: {
176
+ INTEGRATIONS: "/attio/integrations",
177
+ OAUTH_CALLBACK: "/attio/oauth/callback",
178
+ OBJECTS: {
179
+ pattern: "/attio/integrations/:integrationId/objects",
180
+ build: (integrationId: string) => `/attio/integrations/${encodeURIComponent(integrationId)}/objects`,
181
+ params: { integrationId: "string" } as const
182
+ }
183
+ },
184
+
185
+ // Agents routes
186
+ AGENTS: {
187
+ LIST: "/agents",
188
+ RECENT: "/agents/recent",
189
+ BY_ID: {
190
+ pattern: "/agents/:id",
191
+ build: (id: string) => `/agents/${encodeURIComponent(id)}`,
192
+ params: { id: "string" } as const
193
+ }
194
+ },
195
+
196
+ IMPROVEMENTS: {
197
+ BY_AGENT_ID: {
198
+ pattern: "/agents/:agentId/improvements",
199
+ build: (agentId: string) => `/agents/${encodeURIComponent(agentId)}/improvements`,
200
+ params: { agentId: "string" } as const
201
+ },
202
+ APPLY: {
203
+ pattern: "/agents/:agentId/improvements/:id/apply",
204
+ build: (agentId: string, id: string) => `/agents/${encodeURIComponent(agentId)}/improvements/${encodeURIComponent(id)}/apply`,
205
+ params: { agentId: "string", id: "string" } as const
206
+ },
207
+ DISMISS: {
208
+ pattern: "/agents/:agentId/improvements/:id/dismiss",
209
+ build: (agentId: string, id: string) => `/agents/${encodeURIComponent(agentId)}/improvements/${encodeURIComponent(id)}/dismiss`,
210
+ params: { agentId: "string", id: "string" } as const
211
+ },
212
+ UNDO_DISMISS: {
213
+ pattern: "/agents/:agentId/improvements/:id/undo-dismiss",
214
+ build: (agentId: string, id: string) => `/agents/${encodeURIComponent(agentId)}/improvements/${encodeURIComponent(id)}/undo-dismiss`,
215
+ params: { agentId: "string", id: "string" } as const
216
+ },
217
+ TOGGLE_ENABLED: {
218
+ pattern: "/agents/:agentId/improvements-enabled",
219
+ build: (agentId: string) => `/agents/${encodeURIComponent(agentId)}/improvements-enabled`,
220
+ params: { agentId: "string" } as const
221
+ }
222
+ },
223
+
224
+ // Templates routes
225
+ TEMPLATES: "/templates",
226
+ PUBLIC: {
227
+ TEMPLATES: "/public/templates"
228
+ },
229
+
230
+ // Tools routes
231
+ TOOLS: {
232
+ THAT_REQUIRE_APPROVALS: "/tools/that-require-approvals"
233
+ },
234
+
235
+ // Integrations routes
236
+ INTEGRATIONS: {
237
+ INSTALLATION_DETAILS_BY_TYPE: {
238
+ pattern: "/integrations/:integrationType/installation-details",
239
+ build: (integrationType: string) => `/integrations/${encodeURIComponent(integrationType)}/installation-details`,
240
+ params: { integrationType: "string" } as const
241
+ },
242
+ LIST: "/integrations",
243
+ ACTIVE: "/integrations/active"
244
+ },
245
+
246
+ // Notification destinations routes
247
+ NOTIFICATION_DESTINATIONS: {
248
+ LIST: "/notification-destinations",
249
+ BY_ID: {
250
+ pattern: "/notification-destinations/:id",
251
+ build: (id: string) => `/notification-destinations/${encodeURIComponent(id)}`,
252
+ params: { id: "string" } as const
253
+ }
254
+ },
255
+
256
+ // API Tokens routes
257
+ API_TOKENS: {
258
+ LIST: "/api-tokens",
259
+ BY_ID: {
260
+ pattern: "/api-tokens/:id",
261
+ build: (id: string) => `/api-tokens/${encodeURIComponent(id)}`,
262
+ params: { id: "string" } as const
263
+ }
264
+ },
265
+
266
+ // SDK routes (authenticated via API tokens)
267
+ SDK: {
268
+ ME: "/sdk/me",
269
+ SAMPLE_EVENTS: "/sdk/sample-events",
270
+ TOOL_EXECUTE: "/sdk/tool-execute",
271
+ TOOL_DEFINITIONS: "/sdk/tool-definitions",
272
+ AGENT_RUN: "/sdk/agent-run",
273
+ SESSION_EVENTS: "/sdk/session-events",
274
+ DEPLOY: "/sdk/deploy"
275
+ },
276
+
277
+ NOTIFICATION_SETTINGS: "/notification-settings",
278
+
279
+ SENT_NOTIFICATIONS: {
280
+ LIST: "/sent-notifications"
281
+ },
282
+
283
+ PENDING_APPROVALS: {
284
+ LIST: "/pending-approvals"
285
+ },
286
+
287
+ // Webhooks routes
288
+ WEBHOOKS: {
289
+ GMAIL: "/webhooks/gmail",
290
+ FIGMA: "/webhooks/figma",
291
+ WORKOS: "/webhooks/workos",
292
+ JIRA_BY_ACCOUNT_ID: {
293
+ pattern: "/webhooks/jira/:accountId",
294
+ build: (accountId: string) => `/webhooks/jira/${encodeURIComponent(accountId)}`,
295
+ params: { accountId: "string" } as const
296
+ },
297
+ LINEAR_BY_USER_ID: {
298
+ pattern: "/webhooks/linear/:userId",
299
+ build: (userId: string) => `/webhooks/linear/${encodeURIComponent(userId)}`,
300
+ params: { userId: "string" } as const
301
+ },
302
+ SCHEDULE_BY_INPUT_ID: {
303
+ pattern: "/webhooks/schedule/:inputId",
304
+ build: (inputId: string) => `/webhooks/schedule/${encodeURIComponent(inputId)}`,
305
+ params: { inputId: "string" } as const
306
+ },
307
+ WORKOS_TRIGGER_BY_INTEGRATION_ID: {
308
+ pattern: "/webhooks/workos-trigger/:integrationId",
309
+ build: (integrationId: string) => `/webhooks/workos-trigger/${encodeURIComponent(integrationId)}`,
310
+ params: { integrationId: "string" } as const
311
+ }
312
+ },
313
+
314
+ // Schedule routes
315
+ SCHEDULE: {
316
+ TRIGGER_BY_INPUT_ID: {
317
+ pattern: "/schedule/trigger/:inputId",
318
+ build: (inputId: string) => `/schedule/trigger/${encodeURIComponent(inputId)}`,
319
+ params: { inputId: "string" } as const
320
+ },
321
+ TRIGGER_WITH_EVENT: {
322
+ pattern: "/schedule/trigger-with-event/:automationId",
323
+ build: (automationId: string) => `/schedule/trigger-with-event/${encodeURIComponent(automationId)}`,
324
+ params: { automationId: "string" } as const
325
+ }
326
+ },
327
+
328
+ // Refresh tokens route
329
+ REFRESH_TOKENS: "/refresh-tokens",
330
+ REVIEW_AGENTS: "/review-agents",
331
+
332
+ // Users routes
333
+ USERS: {
334
+ CREATE: "/users",
335
+ BY_ID: {
336
+ pattern: "/users/:id",
337
+ build: (id: string) => `/users/${encodeURIComponent(id)}`,
338
+ params: { id: "string" } as const
339
+ }
340
+ },
341
+
342
+ // Builder chat routes
343
+ BUILDER_CHAT: {
344
+ HISTORY_BY_SESSION_ID: {
345
+ pattern: "/builder-chat/:sessionId/history",
346
+ build: (sessionId: string) => `/builder-chat/${encodeURIComponent(sessionId)}/history`,
347
+ params: { sessionId: "string" } as const
348
+ }
349
+ }
350
+ } as const
@@ -0,0 +1,36 @@
1
+ import { IntegrationType } from "./Integrations"
2
+
3
+ export type ApprovalActionType = "open_run_history" | "approve_action" | "reject_action"
4
+ export type ApprovalRequestStatus = "pending" | "in_progress" | "completed"
5
+ export type ApprovalRequestFilter = ApprovalRequestStatus | "all"
6
+
7
+ export type ApprovalAction = {
8
+ type: ApprovalActionType
9
+ label: string
10
+ deepLink: string
11
+ }
12
+
13
+ export type ApprovalRequest = {
14
+ id: string
15
+ icon: IntegrationType
16
+ title: string
17
+ subheader: string
18
+ timestamp: string
19
+ status: ApprovalRequestStatus
20
+ actions: ApprovalAction[]
21
+ runId: string
22
+ agentId: string
23
+ }
24
+
25
+ export type GetPendingApprovalsResponse = {
26
+ items: ApprovalRequest[]
27
+ }
28
+
29
+ export function parseDeepLink(deepLink: string): { type: string; params: string[] } {
30
+ const parts = deepLink.split("|")
31
+ return { type: parts[0], params: parts.slice(1) }
32
+ }
33
+
34
+ export function encodeDeepLink(type: ApprovalActionType, ...params: string[]): string {
35
+ return [type, ...params].join("|")
36
+ }