@mitralab.io/functions-sdk 0.2.6 → 0.2.7

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  All notable changes to this project are documented in this file.
4
4
 
5
+ ## 0.2.7
6
+
7
+ Stable release of the 0.2.7-beta.0 line, already on the `beta` tag. This release only moves the
8
+ Core dependency to its stable number, so no runtime behavior in this package changes.
9
+
10
+ - Depend on `@mitralab.io/sdk-core@0.2.12`, the stable release of the 0.2.12-beta.1 surface: a
11
+ `cancel()` pressed before the agent turn starts waits for the box to admit the prompt and goes out
12
+ right after it.
13
+ - Pin the SDK-PARITY-001 corpus to Core `0.2.12` with its digest and immutable source commit.
14
+
15
+ ## 0.2.7-beta.0
16
+
17
+ - Depend on `@mitralab.io/sdk-core@0.2.12-beta.1`: a `cancel()` pressed before the agent turn starts
18
+ waits for the box to admit the prompt and goes out right after it, instead of being dropped while
19
+ the answer kept coming. `cancelled` is only emitted once the stop was delivered.
20
+ - Pin the SDK-PARITY-001 corpus to Core `0.2.12-beta.1` with its digest and immutable source commit.
21
+
5
22
  ## 0.2.6
6
23
 
7
24
  Stable release of the 0.2.6-beta.0 line, already on the `beta` tag. This release only moves the
package/README.md CHANGED
@@ -1,539 +1,100 @@
1
1
  # Mitra Functions SDK for JavaScript
2
2
 
3
- JavaScript and TypeScript SDK for code running inside Mitra Server Functions. Its native surface exposes the application-scoped Platform APIs that a function commonly needs without requiring browser authentication in the runtime.
3
+ SDK JavaScript e TypeScript para código que roda dentro de uma Server Function da Mitra: dados do app, outras Functions, queries, integrações, agentes e notificações, sempre no escopo do app da Function. Para app de browser, use [`@mitralab.io/platform-sdk`](https://www.npmjs.com/package/@mitralab.io/platform-sdk).
4
4
 
5
- The SDK uses the short-lived platform access token injected into the function runtime. It does not log in users, persist credentials, refresh tokens, use API keys, or retry requests automatically.
6
-
7
- Shared API contracts and modules come from `@mitralab.io/sdk-core`. This package owns only the Server Function runtime adapter: environment configuration, token headers, optional request deadlines, credential redaction, redirect refusal, and one-attempt request policy. The core never receives or stores the token.
8
-
9
- ## Installation
5
+ ## Instalação
10
6
 
11
7
  ```bash
12
8
  npm install @mitralab.io/functions-sdk
13
9
  ```
14
10
 
15
- Node.js 18 or newer is required.
16
-
17
- ## Runtime integration
18
-
19
- The SDK accepts the existing Server Function runtime variables:
11
+ No runtime de Server Functions da Mitra o pacote já vem instalado; instale no projeto para ter os tipos ou para rodar fora do runtime. Node 18 ou mais novo, ou outro runtime com `fetch` global.
20
12
 
21
- - `MITRA_BASE_URL`
22
- - `MITRA_TOKEN`
23
- - `MITRA_PROJECT_ID`
13
+ ## Início rápido
24
14
 
25
- It also accepts the canonical aliases:
15
+ ```javascript
16
+ const { createClient } = require("@mitralab.io/functions-sdk")
26
17
 
27
- - `MITRA_API_URL`
28
- - `MITRA_PLATFORM_ACCESS_TOKEN`
29
- - `MITRA_APP_ID`
30
- - `MITRA_DATA_SOURCE_ID`, retained for runtime compatibility when already resolved
31
- - `MITRA_API_KEY`, read by `createClientFromApiKey()`
18
+ exports.handler = async (event, context) => {
19
+ const mitra = createClient()
32
20
 
33
- When only the existing names are present, the SDK removes a trailing `/legacy` from
34
- `MITRA_BASE_URL` and calls the owning services from that gateway root. It forwards `MITRA_TOKEN`
35
- unchanged as the bearer token and uses `MITRA_PROJECT_ID` as the app identifier. It does not
36
- exchange, refresh, inspect, or alter the token. The deprecated bridge still receives the original
37
- base URL. Neither token name represents a user-defined Function secret.
21
+ const order = await mitra.entities.Order.get(event.orderId)
22
+ const { data: items } = await mitra.entities.OrderItem.filter({ order_id: event.orderId })
38
23
 
39
- ## Quick start
40
-
41
- ```typescript
42
- import { createClient } from "@mitralab.io/functions-sdk"
43
-
44
- const mitra = createClient()
45
-
46
- export async function handler(input: { orderId: string }) {
47
- const order = await mitra.entities.Order.get(input.orderId)
48
- return { order }
24
+ return { order, items }
49
25
  }
50
26
  ```
51
27
 
52
- Once the runtime integration is available, `createClient()` reads the process environment by default. For local development or explicit dependency injection, pass configuration directly:
53
-
54
- ```typescript
55
- const mitra = createClient({
56
- apiUrl: "https://api.example.com",
57
- accessToken: process.env.MITRA_PLATFORM_ACCESS_TOKEN,
58
- appId: "app-id",
59
- dataSourceId: "data-source-id",
60
- })
61
- ```
62
-
63
- `createClientFromEnvironment(env)` is available when a function needs to supply a specific environment object, such as in tests.
64
-
65
- ### Authenticating with an api key
66
-
67
- Outside the Functions runtime there is no token to inject. A process that runs on its own — a cron,
68
- a background collector, another service — authenticates with an api key created in
69
- **Settings -> API keys**:
70
-
71
- ```typescript
72
- import { createClientFromApiKey } from "@mitralab.io/functions-sdk"
73
-
74
- const mitra = await createClientFromApiKey({
75
- apiUrl: "https://api.example.com",
76
- apiKey: process.env.MITRA_API_KEY,
77
- appId: "app-id",
78
- })
79
- ```
80
-
81
- The factory is asynchronous because trading the key for a token is a network call. It fails there,
82
- where the client is built, rather than inside an unrelated call later.
28
+ Dentro do runtime, `createClient()` lê a URL, o token e o app das variáveis de ambiente que a Mitra injeta, então não precisa de argumento.
83
29
 
84
- Which key to create depends on what the process does. A **Business** key reaches the published
85
- product: read and write records, run queries, execute functions and integrations. A **Developer**
86
- key adds authoring — schema, code, publishing. An **Administrator** key belongs to a workspace
87
- rather than a product; the SDK issues the token for the configured `appId` from it, and the
88
- platform decides on that call what this user actually reaches in that product.
30
+ Fora do runtime, num processo seu, autentique com uma API key criada em Configurações, API keys. `createClientFromApiKey()` lê `MITRA_API_URL`, `MITRA_APP_ID` e `MITRA_API_KEY` e já troca a chave por um token, para uma chave errada falhar ali:
89
31
 
90
- The token lasts 48 hours and the exchange returns no refresh token, by design: the key does not
91
- expire and is revoked by deleting it, so the SDK renews by trading the key again. It does this on
92
- its own when a request comes back unauthorized, which is why a process may stay up for weeks. Keep
93
- the key where you keep passwords — it is valid until someone deletes it.
32
+ ```javascript
33
+ const { createClientFromApiKey } = require("@mitralab.io/functions-sdk")
94
34
 
95
- This authentication path expects a server runtime. Never ship an api key in code that reaches a
96
- browser: it would be served to every visitor.
97
-
98
- ## Initialization
99
-
100
- Entity and Custom Query operations use the app identity from the token and `X-App-Id`, so they are
101
- available immediately. Custom Query execution sends only `parameters`; Data Manager resolves its
102
- Data Source from the authenticated app.
103
-
104
- `init()` and the optional `dataSourceId` configuration remain available for source compatibility.
105
- When no Data Source is configured, `init()` resolves the nullable value from Code Studio and is
106
- safe to call concurrently, but native Queries and Entities do not depend on it.
107
-
108
- ```typescript
109
- const mitra = createClient()
110
- await mitra.init()
111
-
112
- const result = await mitra.queries.execute("5df41c69-2a74-4db6-9cca-4af2b473941f", {
113
- status: "active",
114
- })
115
- ```
116
-
117
- ## API
118
-
119
- ### Current user
120
-
121
- ```typescript
122
- const user = await mitra.auth.me()
123
- ```
124
-
125
- The SDK only reads the current authenticated user. Login, logout, browser storage, and token refresh belong to the Platform SDK used by frontend applications.
126
-
127
- ### Entities
128
-
129
- ```typescript
130
- type Task = {
131
- id: string
132
- title: string
133
- status: "pending" | "done"
35
+ async function loadOrder(orderId) {
36
+ const mitra = await createClientFromApiKey()
37
+ return mitra.entities.Order.get(orderId)
134
38
  }
135
-
136
- const tasks = mitra.entities.getTable<Task>("Task")
137
- const { data: recent } = await tasks.list({ sort: "-created_at", limit: 20 })
138
- const { data: pending } = await tasks.filter({ status: "pending" })
139
- const created = await tasks.create({ title: "Review order" })
140
- await tasks.update(created.id, { status: "done" })
141
- await tasks.delete(created.id)
142
-
143
- const dynamic = await mitra.entities.Task.list()
144
39
  ```
145
40
 
146
- Available methods are `list`, `filter`, `get`, `create`, `bulkCreate`, `update`, `delete`, and `deleteMany`.
41
+ ## O que dá para fazer
147
42
 
148
- ### Custom queries
43
+ - `entities.<Tabela>`: `list`, `filter`, `get`, `create`, `bulkCreate`, `update`, `delete` e `deleteMany` nas tabelas do app.
44
+ - `queries`, `customQueries`, `sql` e `schema`: queries salvas, SQL parametrizado e estrutura das tabelas.
45
+ - `functions`, `publicFunctions` e `workflows`: chamar outras Server Functions e workflows do app.
46
+ - `integration.executeByAlias(alias, request)`: chama uma API externa configurada no app, com a credencial guardada na Mitra.
47
+ - `messenger.notify(texto)`: manda uma notificação ao usuário autenticado.
48
+ - `agentTasks.session(...)`: chat com agente, com `send`, `sendAndWait`, `cancel` e eventos como `accepted` e `turnEnd`.
49
+ - `currentApp`: definição, arquivos, build e publicação do app da Function.
50
+ - `functionsAdmin`, `integrationAdmin`, `agents`, `agentConnections`, `agentCredentials`, `imports` e `dataSources`: administração dos recursos do app.
149
51
 
150
- ```typescript
151
- const result = await mitra.queries.execute("5df41c69-2a74-4db6-9cca-4af2b473941f", {
152
- customerId: "customer-id",
153
- })
154
- ```
155
-
156
- ### Server Functions
157
-
158
- `execute` waits for a terminal execution response. `executeAsync` requests asynchronous execution and returns the pending execution record.
159
-
160
- ```typescript
161
- const completed = await mitra.functions.execute("function-id", { orderId: "order-id" })
162
- const pending = await mitra.functions.executeAsync("function-id", { orderId: "order-id" })
163
- const current = await mitra.functions.getExecution(pending.id)
164
- await mitra.functions.cancelExecution(pending.id)
165
- ```
166
-
167
- ### Integrations
168
-
169
- ```typescript
170
- const resource = await mitra.integration.executeResource("resource-id", {
171
- description: "Notebook",
172
- })
173
-
174
- const proxy = await mitra.integration.execute("config-id", {
175
- method: "GET",
176
- endpoint: "/users",
177
- queryParams: { limit: "10" },
178
- })
179
- ```
180
-
181
- Credentials configured for an integration are injected by the Integration service. Do not pass provider credentials through function input.
182
-
183
- Use `integrationAdmin.list()` as the native equivalent of `listIntegrationsMitra`. It calls
184
- `GET /integration/api/v1/template-configs`; the service filters app-scoped runtime tokens to the
185
- current app and returns its real paginated `TemplateConfigSummary` values.
186
-
187
- Native entity methods target the public Data Manager records API, which resolves the app Data
188
- Source from the runtime token. That API does not accept the legacy `jdbcConnectionConfigId`
189
- selector, so records that depend on it remain available only through the deprecated bridge. The
190
- SDK does not emulate that selection with raw SQL.
191
-
192
- ### Native modules
193
-
194
- The native client exposes all 24 application runtime and authoring modules from
195
- `@mitralab.io/sdk-core` directly against the owning services. `currentApp` is an additional
196
- Functions-specific convenience facade over the Core `apps` module:
197
-
198
- | Area | Modules | Service |
199
- | ------------------------ | --------------------------------------------------------------------------------- | --------------------------------------- |
200
- | Identity and members | `auth`, `members` | IAM |
201
- | Data | `dataSources`, `schema`, `entities`, `customQueries`, `queries`, `sql`, `imports` | Data Manager |
202
- | Functions and automation | `functions`, `functionsAdmin`, `agents`, `workflows` | Functions |
203
- | Apps | `apps`, `currentApp`, `context` | Code Studio and composed native modules |
204
- | Agent runtime | `agentTasks`, `agentCredentials`, `agentConnections` | Copilot |
205
- | Integrations | `integration`, `integrationAdmin`, `integrationTemplates`, `integrationResources` | Integration |
206
- | Notifications | `messenger` | Messenger |
207
- | Anonymous execution | `publicFunctions` | Functions public API |
52
+ ## Configuração
208
53
 
209
- These modules do not use the BFF gateway. The BFF remains only behind the deprecated
210
- `mitra-sdk` compatibility exports described below.
54
+ `createClient(config?)` usa o campo de `config` e, quando ele falta, a variável de ambiente. Em teste, `createClientFromEnvironment(env)` lê só do objeto que você passar.
211
55
 
212
- Single-Function `functionsAdmin.create()` and `functionsAdmin.patch()` expose
213
- `cronExpression`, `cronInputJson`, and `cronEnabled` as one composed scheduling unit. On create,
214
- omit all three for no schedule; supplying any one requires a non-blank expression. The new schedule
215
- uses `UTC` and starts `ACTIVE` unless `cronEnabled` is `false`. On patch, null or omitted schedule
216
- fields preserve their stored values, an empty input object clears the scheduled input, and a blank
217
- expression removes the schedule. A non-blank expression can create a missing schedule in `UTC`,
218
- while `cronEnabled` explicitly pauses or resumes it. Schedule composition requires
219
- `SCHEDULE_WRITE` and `FUNCTION_EXECUTE` in addition to the Function write permission.
56
+ | Campo | Variável | Obrigatório | Uso |
57
+ | ------------- | ---------------------------------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
58
+ | `apiUrl` | `MITRA_API_URL` ou `MITRA_BASE_URL` | sim | URL HTTP ou HTTPS do API gateway da Mitra, sem credencial, query ou fragmento |
59
+ | `accessToken` | `MITRA_PLATFORM_ACCESS_TOKEN` ou `MITRA_TOKEN` | sim, exceto com API key | token do runtime, enviado como `Bearer` |
60
+ | `appId` | `MITRA_APP_ID` ou `MITRA_PROJECT_ID` | sim | app em que o cliente atua |
61
+ | `apiKey` | `MITRA_API_KEY` | só em `createClientFromApiKey` | chave do app, para processo fora do runtime |
62
+ | `timeoutMs` | | não | prazo por requisição; sem ele, o SDK não impõe prazo, e dentro de uma Function vale o limite de tempo dela |
63
+ | `fetch` | | não | implementação de `fetch`; sem ela, usa a global |
64
+ | `WebSocket` | | não | implementação de WebSocket, como a do pacote `ws`, para a sessão de agente usar socket; sem ela, vale o WebSocket global, se houver, ou HTTP |
220
65
 
221
- Function `get()` and `list()` include all three cron fields when the caller has `SCHEDULE_READ`.
222
- Without it, the fields are all null without consulting Scheduler. A Function with no schedule has
223
- the same all-null shape, so those responses alone cannot distinguish absence from missing read
224
- permission. Function bulk create, update, and patch prohibit all three cron fields; use the
225
- single-Function methods for composed scheduling.
66
+ ## Erros
226
67
 
227
- The native SDK deliberately has no separate schedule lifecycle methods. Create, patch, get, and
228
- list keep Function state and its composed cron fields in one contract.
68
+ `MitraApiError` traz `status`, `code`, `details`, `requestId` e `retryable`. O token não aparece na mensagem nem nos detalhes.
229
69
 
230
- ### Live Agent sessions
70
+ | Erro | Quando | O que fazer |
71
+ | ---------------------------------------------- | --------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
72
+ | `MitraConfigurationError` | configuração ausente ou inválida, ou `apps` usado com outro app | confira variáveis e argumentos; para o próprio app, use `currentApp` |
73
+ | `MitraApiError` `401` ou `403` | o token não dá acesso ao recurso | confira as permissões do app; nem todo módulo está liberado para o token do runtime |
74
+ | `MitraApiError` `429` ou `5xx` | limite de requisições ou falha no servidor | repita só se a operação puder ser repetida |
75
+ | `REQUEST_TIMEOUT`, `NETWORK_ERROR` | prazo estourado ou falha de rede, com `status` `0` | aumente `timeoutMs` ou repita, se a operação permitir |
76
+ | `INVALID_CREDENTIALS`, `AUTHENTICATION_FAILED` | a troca da API key falhou | confira a chave e o `appId` |
77
+ | `INVALID_RESPONSE` | resposta fora do formato esperado | atualize o SDK; se continuar, abra uma issue |
78
+ | `AgentTaskTurnError` | o turno do agente foi recusado ou terminou com erro | leia o `code` e decida se manda de novo |
231
79
 
232
- `agentTasks.session()` adds the Core session state machine to the native Copilot task module.
233
- Core also owns the direct channel to the chat's box: the session asks the Copilot where the chat
234
- is served (`POST /copilot/api/v1/tasks/{taskId}/channel`) and then talks to that box, which runs
235
- the turn. This package only wires the channel to the client's API URL and WebSocket.
80
+ ## Boas práticas
236
81
 
237
- Only an agent chat, a task with an `agentId`, goes to the box, whether the session creates it or
238
- opens it with `session({ taskId })`. A chat without `agentId` keeps the Copilot stream and inputs
239
- as before and never asks for the channel.
82
+ - Crie o cliente dentro do handler. O token do runtime vale para aquela execução e dura pouco.
83
+ - O SDK faz uma tentativa por requisição e não repete, para não gravar duas vezes. `retryable` é só uma dica. O cliente por API key é a exceção: num `401`, ele pega um token novo e repete aquela requisição uma vez.
84
+ - Para o app da Function, use `currentApp`. `apps` só aceita o próprio app, e `apps.list()` e `apps.create()` não existem aqui.
85
+ - Function que só dispara um prompt para um agente pode retornar depois do evento `accepted`. Antes dele, o prompt pode se perder.
86
+ - `cancel()` chamado enquanto o prompt ainda está a caminho espera a box aceitar a mensagem e só então interrompe o turno; aguarde a promessa dele antes de dar o chat por parado. Se a box recusar a mensagem, nenhum stop sai e o evento `cancelled` não é emitido, então o stop não interrompe um turno seguinte.
87
+ - API key fica em variável de ambiente de processo de servidor, nunca em código de browser nem no repositório.
240
88
 
241
- ```typescript
242
- const session = mitra.agentTasks.session({
243
- create: true,
244
- agentId: "agent-id",
245
- agentType: "CODEX",
246
- })
89
+ ## Migração do `mitra-sdk`
247
90
 
248
- session.on("delta", ({ delta, kind }) => {
249
- console.log(kind, delta)
250
- })
91
+ Os exports do SDK legado continuam neste pacote, marcados `@deprecated`, para código de Function existente trocar a dependência sem reescrever os imports. `createClient()` configura o legado com o mesmo token e o mesmo app. Os tipos do Core que têm nome igual a um tipo legado saem com prefixo `Core`, como `CoreAgentConnection`.
251
92
 
252
- const result = await session.sendAndWait("Summarize today's orders")
253
- console.log(result.content)
254
- session.close()
255
- ```
256
-
257
- Existing tasks use `mitra.agentTasks.session({ taskId })`. A new agent chat is created on the
258
- box runtime (`runtime: "T3"`) unless the session names another runtime.
259
-
260
- `transport` picks how the session tries to reach the box:
261
-
262
- - `auto`, the default, uses the box WebSocket when the runtime has one and the box HTTP routes
263
- otherwise: a `POST` per message and a Server-Sent Events (SSE) stream for events.
264
- - `http` uses the box HTTP routes.
265
- - `websocket` uses the box WebSocket.
266
-
267
- Until the box offers the route the session asks for, the session falls back to the Copilot and
268
- says so with `channelDeclined` (see below). The transport is a preference, not a guarantee.
269
-
270
- The Serverless Functions runtime runs Node 20, which has no global `WebSocket`, so sessions
271
- there reach the box over HTTP. Node 22 and newer have one. To use the socket on a runtime without
272
- it, pass an implementation such as `ws` when you create the client; this package does not depend
273
- on one:
274
-
275
- ```typescript
276
- import WebSocket from "ws"
277
-
278
- const mitra = createClient({ WebSocket })
279
- ```
280
-
281
- The box is reached through the channel URL the Copilot returns, which carries a short-lived
282
- grant; the runtime token is never sent to the box. The box routes use `globalThis.fetch`, not the
283
- `fetch` given to the client, so a custom fetch that adds `Authorization` cannot leak the token
284
- there. Core follows only a channel on the configured
285
- API host or a Mitra box host. When the Copilot offers no channel, or the offer cannot be followed
286
- (for example a `websocket` session with no WebSocket available), the session stays on the
287
- Copilot: it opens `GET /copilot/api/v1/tasks/{taskId}/events` as an SSE stream with the runtime
288
- token in `Authorization` plus `X-App-Id`, and sends input to `POST /inputs`. That fallback is
289
- never silent: the session first emits a `raw` event of type `channelDeclined` with the reason.
290
-
291
- `timeoutMs` also bounds `POST /channel`, which the Copilot holds open while the box boots. A
292
- short `timeoutMs` can abort that request, and the session then falls back to the Copilot with
293
- `channelDeclined` reason `unavailable`; leave it unset, or above the box boot time, for agent
294
- chats. On the Copilot stream, `timeoutMs` applies only while waiting for the SSE response
295
- headers. The parser ignores `hello` and `ping` keepalives, and a stream silent for 60 seconds counts
296
- as a disconnect; Core then reconnects once and reconciles persisted messages. The box channel has
297
- its own handshake, silence, redial, and admission deadlines in Core.
298
-
299
- #### Send and return
300
-
301
- A Function does not have to wait for the whole turn. Once the box admits the message, the turn
302
- runs and is recorded without the Function, so it can send, wait for `accepted`, and return:
303
-
304
- ```typescript
305
- export async function handler(input: { taskId: string; prompt: string }) {
306
- const session = mitra.agentTasks.session({ taskId: input.taskId })
307
- try {
308
- await new Promise<void>((resolve, reject) => {
309
- session.on("accepted", () => resolve())
310
- session.on("error", ({ code, error }) =>
311
- reject(new Error(code ? `${code}: ${error}` : error)),
312
- )
313
- session.send(input.prompt)
314
- })
315
- return { accepted: true }
316
- } finally {
317
- session.close()
318
- }
319
- }
320
- ```
321
-
322
- `accepted` fires when the box starts the admitted turn, or after the Copilot's `202` on the
323
- fallback. A refusal fires `error` instead, and a box that does not answer fails the send after
324
- 35 seconds. Returning before `accepted` may lose the message.
325
-
326
- ### App-scoped Code Studio access
327
-
328
- The Functions runtime is fixed to the configured `appId`. `apps.list()` and `apps.create()`
329
- reject locally because they are tenant-level operations. Every other `apps` method rejects
330
- an app ID different from the configured runtime app before making a request.
331
-
332
- Use `currentApp` when possible. It exposes the same current-app lifecycle without repeating
333
- the app ID:
334
-
335
- ```typescript
336
- const app = await mitra.currentApp.get()
337
- const published = await mitra.currentApp.get({ version: "PUBLISHED" })
338
- await mitra.currentApp.update({ name: "Orders" })
339
- await mitra.currentApp.mergeFiles({ "src/generated.ts": "export const ready = true" })
340
- const previewDeploy = await mitra.currentApp.build()
341
- await mitra.currentApp.publish({ externalAccess: true })
342
- ```
343
-
344
- `build()` returns the `AppDeploy` created for preview polling. `get()` preserves the Core
345
- `AppGetOptions`, and `publish()` preserves `AppPublishOptions`.
346
-
347
- The client-side check prevents accidental cross-app calls, but it is not a security boundary.
348
- Code Studio must also enforce the JWT `app_id` claim in the backend. Until that enforcement is
349
- deployed, the access token must be treated as sensitive even though this SDK fixes the app ID.
350
-
351
- ### Public Functions
352
-
353
- `publicFunctions` calls `/functions/public/v1` with a dedicated anonymous transport. It never
354
- sends `Authorization` or `X-App-Id`.
355
-
356
- ```typescript
357
- const result = await mitra.publicFunctions.execute("public-function-id", { value: 1 })
358
- const queued = await mitra.publicFunctions.executeAsync("public-function-id", { value: 1 })
359
- ```
360
-
361
- An asynchronous public execution returns its ID and initial status as fire-and-forget. The public
362
- API does not expose anonymous polling or cancellation. Use synchronous `execute` when the caller
363
- needs the result, or authenticated `functions.executeAsync` plus `functions.getExecution` when the
364
- caller has an app-scoped token.
365
-
366
- ## Runtime authorization
367
-
368
- The JWT `app_id` claim is the authority for application scope. `X-App-Id` carries runtime
369
- context for protected service requests and must not be used by a backend as the authorization
370
- boundary.
371
-
372
- Against the current `origin/alpha` service and IAM policies, 109 of the 120 MCP capabilities
373
- are usable or authorizable from an app-scoped Server Function. The `dataSources.bulk*` methods
374
- compose the existing singular Data Manager endpoints, so they do not require a coordinated
375
- service rollout. The remaining capabilities have these known constraints:
376
-
377
- | Capability | Runtime behavior | Reason |
378
- | ------------------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
379
- | Member reads through `members.list()` | `403 INSUFFICIENT_PERMISSIONS` | `MEMBER_READ` is deliberately absent from the SF token policy. App context excludes members. |
380
- | Function secret list/create/delete | `403 INSUFFICIENT_PERMISSIONS` | `FUNCTION_SECRET_READ`, `FUNCTION_SECRET_WRITE`, and `FUNCTION_SECRET_DELETE` are absent from the SF token policy. |
381
- | Agent runtime operations | Configuration or service rejection without an agent context | The runtime must inject or otherwise provide the applicable `agent_id`. |
382
- | `apps.list()` and `apps.create()` | Local `MitraConfigurationError` | Tenant-level app collection operations are not applicable to an app-scoped runtime. |
383
- | `messenger.notify()` | Depends on the authenticated user's channel | The call is authorized, but delivery requires a configured notification channel. |
384
-
385
- The methods remain part of the typed API so clients with a different authorized token can use
386
- the shared contract. This SDK does not broaden IAM permissions or retry a rejected operation.
387
-
388
- ### Core and legacy type names
389
-
390
- The deprecated `AgentConnection`, `AgentMessage`, `AgentModel`, and `ListTablesOptions` names keep
391
- their original `mitra-sdk` meanings for source compatibility. Import the native Core contracts as
392
- `CoreAgentConnection`, `CoreAgentMessage`, `CoreAgentModel`, and `CoreListTablesOptions`.
393
-
394
- The deprecated package also owns `AgentTaskSession`, `AgentTimelineItem`, and `AgentToolEvent`.
395
- Their native equivalents are exported as `CoreAgentTaskSession`, `CoreAgentTimelineItem`, and
396
- `CoreAgentToolEvent`. New session options and results are available as
397
- `CoreAgentTaskSessionOptions`, `AgentSendOptions`, `AgentSendAndWaitOptions`, and `AgentTurnResult`.
398
- `sendAndWait()` rejects Agent turn failures with `AgentTaskTurnError`, preserving the service error
399
- code when one is present.
400
-
401
- ## Errors and request behavior
402
-
403
- API, timeout, invalid response, and network failures throw `MitraApiError`. The error exposes `status`, `code`, `details`, `requestId`, and `retryable`, preserving API metadata when it is provided. Configuration failures throw `MitraConfigurationError`.
404
-
405
- When an API error omits `retryable`, the HTTP adapter classifies 4xx responses
406
- as `false` and 5xx responses as `true`. This field is diagnostic classification
407
- only. The SDK still makes one attempt and never retries a request automatically.
408
-
409
- The Python package uses idiomatic specialized names for local failures. JavaScript `REQUEST_TIMEOUT` and `NETWORK_ERROR` map to Python `MitraNetworkError`, while JavaScript `INVALID_RESPONSE` maps to Python `MitraResponseError`. API responses use `MitraApiError` in both packages.
410
-
411
- Every protected request sends `Authorization: Bearer <token>` and `X-App-Id`. Public Function
412
- requests send neither header. Requests have no adapter-level deadline by default, so normal
413
- long-running platform operations remain governed by the Server Function runtime. Set `timeoutMs`
414
- to opt into a per-request deadline. Requests are never retried automatically, which avoids
415
- replaying writes with unknown idempotency.
416
-
417
- The access token is redacted from API error messages and error details.
418
-
419
- ## Contract parity
420
-
421
- The test suite reads SDK-PARITY-001 version 0.2.0-beta.1 directly from the installed
422
- `@mitralab.io/sdk-core` package. The `sdk-core-v0.2.0-beta.1` manifest pins the expected package
423
- version, contract path, SHA-256 digest, and immutable source commit. The release gate rejects
424
- publication unless the installed corpus matches its raw GitHub source byte for byte.
425
-
426
- The JavaScript consumer requirement is exactly `httpAdapterCases: all`. Tests
427
- execute all recorded 404, 503, and timeout cases through the public client and
428
- the real `HttpClient`, using a mock fetch only at the network boundary. They
429
- verify the request and the complete error semantics. Continuous integration and
430
- release gates also download the canonical file from the public Core repository
431
- at the pinned commit and compare it byte for byte with the installed package.
432
-
433
- ## Scope
434
-
435
- The current draft expands the native client from the initial runtime operations to the complete
436
- Core 0.2.0-beta.1 module surface listed above. Availability still depends on the runtime token
437
- resources and the service constraints in the authorization matrix.
438
-
439
- ## Legacy compatibility
440
-
441
- The runtime and type surface of `mitra-sdk@1.0.63-beta.39` is re-exported so existing Server
442
- Function code can adopt `@mitralab.io/functions-sdk` without an import rewrite. Browser-only
443
- bindings that exist only in `mitra-interactions-sdk`, including login and token refresh, are not
444
- part of this package. Every re-export is the legacy binding itself, unchanged, and is marked
445
- `@deprecated` with the new equivalent when one exists. Native raw SQL is available through `sql`;
446
- app authoring and Agent runtime modules cover most builder and Agent SDK operations. Builder-specific
447
- Git and direct-S3 flows have no one-to-one replacement and remain supported through the legacy
448
- exports. Live Agent sessions have a native replacement through `agentTasks.session()`.
449
-
450
- `getGitConfigMitra` remains legacy-only because credential minting is an internal Sandbox POST
451
- authenticated between services and is not published for app tokens. The Sandbox already owns Git
452
- setup and token renewal for Agent workspaces; the native Functions client does not expose that
453
- secret-producing endpoint.
454
-
455
- ```typescript
456
- import { createClient, listProjectsMitra } from "@mitralab.io/functions-sdk"
457
-
458
- createClient()
459
- const projects = await listProjectsMitra()
460
- ```
461
-
462
- `createClient()` and `createClientFromEnvironment()` configure the deprecated SDK with
463
- `MITRA_BASE_URL`, the resolved access token, and the app ID, so legacy code does not read the
464
- environment itself. Native modules use the canonical API root directly and never route through the
465
- BFF, even when that root was derived from an existing `MITRA_BASE_URL` value.
466
- For explicit local configuration, `legacyBaseUrl` selects the deprecated BFF base; it falls back to
467
- `apiUrl` only when omitted. The deprecated SDK receives `appId` as its `projectId` and accepts the
468
- access token with or without a `Bearer` prefix.
469
-
470
- The direct legacy dependency is pinned to the exact `mitra-sdk` version. Nothing in it is modified
471
- or published by this package.
472
-
473
- ## Development
93
+ ## Desenvolvimento
474
94
 
475
95
  ```bash
476
- npm install
96
+ npm ci
477
97
  npm run check
478
98
  ```
479
99
 
480
- The adapter pins `@mitralab.io/sdk-core@0.2.0-beta.1` exactly and installs it from the public npm
481
- registry, so the checked-in `package-lock.json` carries the registry `resolved` URL and integrity
482
- for that exact version and `npm ci` reproduces it. Do not use a `file:` dependency or `npm link`.
483
-
484
- To validate against a Core build that is not published yet, supply a tarball without changing
485
- dependency metadata or the final lockfile:
486
-
487
- ```bash
488
- npm install --no-save --package-lock=false /path/to/mitralab.io-sdk-core-0.2.0-beta.1.tgz
489
- npm run lint && npm run typecheck && npm test && npm run build
490
- MITRA_SDK_CORE_TARBALL=/path/to/mitralab.io-sdk-core-0.2.0-beta.1.tgz npm run smoke:package
491
- git diff --exit-code -- package-lock.json
492
- ```
493
-
494
- ## Release order
495
-
496
- Core moves first, then this package follows. `<core-version>` below is the Core release being
497
- adopted, for example `0.2.0-beta.1`.
498
-
499
- 1. Merge and publish `@mitralab.io/sdk-core@<core-version>` under npm's `beta` dist-tag from its
500
- immutable source commit.
501
- 2. Add `contracts/sdk-core-v<core-version>.manifest.json` carrying that full commit SHA:
502
-
503
- ```json
504
- {
505
- "source": {
506
- "repository": "https://github.com/mitralab-dev/mitra-core-sdk",
507
- "commit": "<full-core-commit-sha>",
508
- "path": "contracts/v<core-version>/sdk-parity.json"
509
- }
510
- }
511
- ```
512
-
513
- Point `scripts/check-contract-corpus.mjs` and the tests that read a manifest at the new file, so
514
- the gate verifies the version being adopted.
515
-
516
- 3. Run `npm install --package-lock-only`, then verify that the Core lock entry is exactly
517
- `<core-version>` with an npm registry URL and integrity.
518
- 4. Run `npm ci`, `npm run check`, and `npm run check:contracts:source`.
519
- 5. Publish this package under npm's `beta` dist-tag through the release workflow and run the
520
- tarball smoke against the registry.
521
-
522
- Steps 1 to 3 are already done for the current `0.2.0-beta.1` pin: Core is published, the manifest
523
- carries its immutable source commit, and the lock records the registry `resolved` URL and integrity.
524
- Steps 4 and 5 remain.
525
-
526
- Stable `X.Y.Z` releases use npm's default `latest` dist-tag. The workflow accepts only that stable
527
- form or the prerelease form `X.Y.Z-beta.N`.
528
-
529
- `prepublishOnly` repeats the immutable-source check, so a direct `npm publish` cannot bypass the
530
- pending Core provenance.
531
-
532
- The contract source can be checked explicitly without changing the manifest or
533
- lockfile:
534
-
535
- ```bash
536
- node scripts/check-contract-corpus.mjs --canonical /path/to/sdk-parity.json
537
- ```
538
-
539
- The package builds ESM, CommonJS, and TypeScript declarations in `dist/`. Tests enforce at least 80 percent coverage for lines, functions, branches, and statements.
100
+ O `check` roda format, lint, typecheck, testes, build, a conferência dos exports e do contrato com o Core, e um smoke test do pacote. A publicação no npm sai do workflow Release.
@@ -0,0 +1,15 @@
1
+ {
2
+ "contract": "SDK-PARITY-001",
3
+ "version": "0.2.12-beta.1",
4
+ "dependency": {
5
+ "package": "@mitralab.io/sdk-core",
6
+ "version": "0.2.12-beta.1",
7
+ "contractPath": "contracts/v0.2.12-beta.1/sdk-parity.json"
8
+ },
9
+ "sha256": "272749b53557c5bd2a2160f6eed071933f22bd9b1d14c55e610a875f54e29ac3",
10
+ "source": {
11
+ "repository": "https://github.com/mitralab-dev/mitra-core-sdk",
12
+ "commit": "bbbf59254db9ccff87ea93e5f5ad1a29c278c5df",
13
+ "path": "contracts/v0.2.12-beta.1/sdk-parity.json"
14
+ }
15
+ }
@@ -0,0 +1,15 @@
1
+ {
2
+ "contract": "SDK-PARITY-001",
3
+ "version": "0.2.12",
4
+ "dependency": {
5
+ "package": "@mitralab.io/sdk-core",
6
+ "version": "0.2.12",
7
+ "contractPath": "contracts/v0.2.12/sdk-parity.json"
8
+ },
9
+ "sha256": "685238cadcf898128a5dad60c30bcdd8dcc9a02f03077d765aee01f8d6e34709",
10
+ "source": {
11
+ "repository": "https://github.com/mitralab-dev/mitra-core-sdk",
12
+ "commit": "8a9bed056b49f3ffba79bd1acf14609c71e2abb4",
13
+ "path": "contracts/v0.2.12/sdk-parity.json"
14
+ }
15
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mitralab.io/functions-sdk",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "JavaScript and TypeScript SDK for Mitra Server Functions",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -67,7 +67,7 @@
67
67
  "node": ">=18.0.0"
68
68
  },
69
69
  "dependencies": {
70
- "@mitralab.io/sdk-core": "0.2.11",
70
+ "@mitralab.io/sdk-core": "0.2.12",
71
71
  "mitra-sdk": "1.0.63-beta.42"
72
72
  },
73
73
  "devDependencies": {