@lotics/app-sdk 0.56.0 → 0.56.1

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/AGENTS.md CHANGED
@@ -20,7 +20,7 @@ signature; open the file.**
20
20
  | [docs/files.md](./docs/files.md) | Files end to end — `useFileUpload`, `useAttachments`, `readFiles`/presigned URLs, workflow-generated files, preview pairing, filter operators, the server-side delivery bounds. |
21
21
  | [docs/members_and_options.md](./docs/members_and_options.md) | People + select options + comments — `useMembers`, `useFieldOptions`, `useViewer`, `useComments`, and the `@lotics/ui` components they feed. |
22
22
  | [docs/navigation_and_state.md](./docs/navigation_and_state.md) | `AppRouter` (embedded/standalone URL model), `useUrlState` + `urlParam` codecs, `useRecents`. |
23
- | [docs/ai.md](./docs/ai.md) | `useAgentRun` (structured vs free-text, streaming ai-sdk `parts` → `AgentRun`, the agent's ask-back — `pendingChoice`/`answerChoice` over the parked `awaiting_input` state), `askAi` — plus the fields-vs-file razor for choosing between them — and `useAiContext` (push the current screen's view state to the member's ambient chat agent; caps, push-only semantics, auto query-refetch on chat mutation). |
23
+ | [docs/ai.md](./docs/ai.md) | `useAgentRun` (structured vs free-text, streaming ai-sdk `parts` → `AgentRun`, the agent's ask-back — `pendingChoice`/`answerChoice` over the parked `awaiting_input` state), `askAi` — plus the fields-vs-file razor for choosing between them — and `useAiContext` (push the current screen's view state to the member's ambient chat agent; caps, push-only semantics, auto query-refetch on chat mutation). **A `file` input carries its own content** — images/PDFs are perceived natively, Word/Excel/CSV/text are materialized into the run; no reader tool to declare. |
24
24
  | [docs/security.md](./docs/security.md) | **Read before shipping** — the owner-principal model, `is_current_member` scoping, write attribution, group gates, public-app bounds, what runtime refinement cannot widen. |
25
25
  | [docs/runtime.md](./docs/runtime.md) | `mount()`, the two transports, `rpc()`, `openExternal`/`downloadFile`, geofencing, analytics, `useConfig` (App-Packages installation config), `getAppBinding` (package apps' runtime `F`/`OPT`/`ROLE` resolution via the generated `.lotics/app_fields.ts`), and the publish chain for package contributors. |
26
26
 
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * Browser-side image compression for app uploads.
3
3
  *
4
- * Phone-camera photos are huge (4–10 MB HEIC/JPEG) but documents only need
5
- * legible bytes, not megapixel ones. Resize to ≤1280px on the long edge and
6
- * re-encode as JPEG at q=0.75 before uploadingtypically 10–20× smaller
7
- * with no visible quality loss for the doc-scan use case.
4
+ * Phone-camera photos are huge (4–10 MB HEIC/JPEG) and no document needs
5
+ * megapixels. Resize to ≤1568px on the long edge — the vision model's own
6
+ * working resolution, above which the provider downsamples anyway and
7
+ * re-encode as JPEG at q=0.9, which keeps small glyphs (container numbers,
8
+ * invoice lines) legible to a reader and to an extraction agent.
8
9
  *
9
10
  * HEIC/HEIF / PNG / WebP are converted to JPEG. Non-image files (PDF, etc.)
10
11
  * pass through unchanged. Falls through gracefully on any browser API gap
@@ -1,10 +1,11 @@
1
1
  /**
2
2
  * Browser-side image compression for app uploads.
3
3
  *
4
- * Phone-camera photos are huge (4–10 MB HEIC/JPEG) but documents only need
5
- * legible bytes, not megapixel ones. Resize to ≤1280px on the long edge and
6
- * re-encode as JPEG at q=0.75 before uploadingtypically 10–20× smaller
7
- * with no visible quality loss for the doc-scan use case.
4
+ * Phone-camera photos are huge (4–10 MB HEIC/JPEG) and no document needs
5
+ * megapixels. Resize to ≤1568px on the long edge — the vision model's own
6
+ * working resolution, above which the provider downsamples anyway and
7
+ * re-encode as JPEG at q=0.9, which keeps small glyphs (container numbers,
8
+ * invoice lines) legible to a reader and to an extraction agent.
8
9
  *
9
10
  * HEIC/HEIF / PNG / WebP are converted to JPEG. Non-image files (PDF, etc.)
10
11
  * pass through unchanged. Falls through gracefully on any browser API gap
@@ -15,8 +16,10 @@
15
16
  * dependency-free (no logger, no UploadIntent abstraction) so the SDK ships
16
17
  * as a single drop-in.
17
18
  */
18
- const MAX_IMAGE_DIMENSION_PX = 1280;
19
- const JPEG_QUALITY = 0.75;
19
+ // MIRRORS `@lotics/shared/image_policy` — the SDK ships dependency-free so it
20
+ // cannot import it. Change both together.
21
+ const MAX_IMAGE_DIMENSION_PX = 1568;
22
+ const JPEG_QUALITY = 0.9;
20
23
  const CONVERTIBLE_EXTENSION_PATTERN = /\.(heic|heif|png|webp)$/i;
21
24
  export async function optimizeImageForUpload(file) {
22
25
  const format = getOptimizableFormat(file);
package/docs/ai.md CHANGED
@@ -20,7 +20,7 @@ A declaration carries:
20
20
  | Field | Meaning |
21
21
  |---|---|
22
22
  | `instructions` | System instructions — the task the agent performs per run |
23
- | `tool_names` | The tools the agent may call, resolved against the platform's automation tool registry. **This is the capability boundary** — the run can use nothing else. May be empty for a pure-reasoning agent |
23
+ | `tool_names` | The tools the agent may call, resolved against the platform's automation tool registry. **This is the capability boundary** — the run can use nothing else. May be empty — including for an agent that reads documents, since a [`file` input carries its own content](#file-inputs--what-the-agent-can-actually-see) |
24
24
  | `model_id` | The chat model the agent runs on |
25
25
  | `effort_level` | Optional reasoning depth for adaptive-thinking models |
26
26
  | `inputs` | Optional typed input schema for one run — the same vocabulary as workflow inputs (`text`, `number`, `file`, `member`, `record_link`, `select`, …). The server validates every run payload against it |
@@ -181,9 +181,21 @@ On recovery, `output` adopts the row's output **only when it is an object** (a s
181
181
 
182
182
  Sessions are scoped to the authenticated member who ran them: two members using the same `sessionId` string share nothing, and a member can never read or extend another member's thread.
183
183
 
184
- ### File inputs vision
184
+ ### File inputs what the agent can actually see
185
185
 
186
- A declared `file` input (single or `multi`) is materialized into the model's native perception when the type supports it: **`image/*` becomes a vision part, `application/pdf` a document part** — the agent literally sees the file, no OCR tooling needed. Any other type (docx, xlsx, csv, …) is passed as a `file_id` reference instead; the agent can only open it if a file-reading tool is in its declared `tool_names`. Every file in a `multi` input is materialized — nothing is collapsed to the first. Get the ids from [`useFileUpload` / `useAttachments`](./files.md).
186
+ **A `file` input carries its own content. You do not declare a tool to read it.**
187
+
188
+ | Tier | Types | How the agent gets it |
189
+ |---|---|---|
190
+ | **Perceived natively** | `image/*`, `application/pdf` | A vision / document part — the agent literally sees it |
191
+ | **Materialized** | Word (`.docx`/`.doc`), Excel (`.xlsx`/`.xls`), CSV, and text (`.txt`, `.md`, `.json`, `.eml`, `.html`, `.xml`, `.yaml`) | Read server-side by the same engines `view_files` uses and inlined into the run's message, truncated at 40,000 characters with the agent told when that happened |
192
+ | **Unreadable** | Archives, audio, video | The run fails immediately, naming the file — a fact about the upload, not a gap in your configuration |
193
+
194
+ Every file in a `multi` input is materialized — nothing is collapsed to the first. Get the ids from [`useFileUpload` / `useAttachments`](./files.md).
195
+
196
+ **Why no tool:** the content ends up in the agent's context either way, so making it fetch what the server already holds costs a model round-trip and buys nothing. It also keeps the capability boundary tight — an agent that reads its own input never gains the ability to read *other* files in the workspace.
197
+
198
+ **When to add a tool anyway.** Only to reach *past* what was inlined. A spreadsheet is materialized at 100 rows × 50 columns per sheet and a Word file at 1,000 elements; overflow is reported, never silent. If the agent must read row 4,000 of a large sheet, add `excel_get_range` / `excel_find_cells` (or `view_files` for an ad-hoc second look at a different file).
187
199
 
188
200
  ### Auth, quota, and bounds
189
201
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/app-sdk",
3
- "version": "0.56.0",
3
+ "version": "0.56.1",
4
4
  "description": "Runtime SDK for Lotics custom-code apps — typed hooks, postMessage bridge, mount entry point",
5
5
  "type": "module",
6
6
  "exports": {