@lotics/app-sdk 0.62.1 → 0.62.3

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/docs/ai.md CHANGED
@@ -22,7 +22,7 @@ A declaration carries:
22
22
  | `instructions` | System instructions — the task the agent performs per run |
23
23
  | `tool_names` | The tools the agent may call, resolved against the platform's automation tool registry. The capability boundary for everything EXCEPT workspace data — 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
  | `knowledge_doc_ids` | The knowledge docs the agent may read, and the whole set it can reach — a doc absent from this list is unreadable even if the agent names its id. Declare `grep_knowledge` / `read_knowledge` in `tool_names` to read them. There is no size limit and nothing is inlined, so a multi-megabyte reference corpus (a full tariff, a regulation set) is a normal declaration. Reach for `code_exec` only to COMPUTE across the corpus — counting, cross-referencing — never merely to read it |
25
- | `query_aliases` | The app's own named queries the agent may run via `run_app_query` — its **entire read surface** over records |
25
+ | `query_aliases` | The app's own named queries the agent may run via `run_app_query` — its **entire read surface** over records. You list them; there is no "all of them" shorthand, and adding a query to the app never widens an existing agent. Omitted means the agent reads nothing |
26
26
  | `workflow_aliases` | The app's own workflows the agent may invoke via `run_app_workflow` — its **entire write surface** |
27
27
  | `model_id` | Optional chat model pin. Omit (preferred) to follow the platform default chat model, resolved at run time — the agent tracks model generations with no rewrite. Pin only a deliberate, tested choice |
28
28
  | `effort_level` | Optional reasoning depth for adaptive-thinking models. Requires an explicit `model_id` pin — effort is tuned per model |
@@ -337,6 +337,13 @@ gated per turn on `app:use` for the app in the member's workspace, and runs
337
337
  under the app's OWNER authority with `is_current_member` bound to the MEMBER
338
338
  (exactly as the app's own UI does).
339
339
 
340
+ The agent is handed a **catalog** of those aliases — each one's params and its
341
+ `description` (a query's own, [declared in the manifest](./queries.md); a
342
+ workflow's, off its workflow row) — so it picks the right one instead of
343
+ guessing an alias and learning the list from a refusal. Your descriptions are
344
+ what it reads, on this surface and inside your own agents' runs. They enter the
345
+ prompt as a capability listing, never as instructions.
346
+
340
347
  **Writes carry a second gate that reads do not: `run_app_workflow` asks the
341
348
  member to approve every call from chat.** A wrong read is fixed by asking
342
349
  again; a wrong write is not. The alias list bounds what an agent *could* reach;
package/docs/queries.md CHANGED
@@ -35,7 +35,8 @@ Queries live in the app's `package.json` under `lotics.queries` — an alias →
35
35
  },
36
36
  "orderByCode": {
37
37
  "ast": { /* … a filter with "{{params.code}}" … */ },
38
- "params": { "code": { "type": "text" } }
38
+ "params": { "code": { "type": "text" } },
39
+ "description": "One order by its code, with its customer and line total."
39
40
  }
40
41
  }
41
42
  }
@@ -48,9 +49,15 @@ Queries live in the app's `package.json` under `lotics.queries` — an alias →
48
49
  (`text`, `number`, `boolean`, `date`, `datetime`, `email`, `select`, `member`, `record_link`,
49
50
  `date_range`, `file`, `json`, `object`, `array`); each param may set `required: false`
50
51
  (default is required) and `description`. Nesting is capped at depth 8.
52
+ - **`description`** — one line saying what the query returns, capped at 300 characters. No app
53
+ code reads it. It is for the **agents** that reach this app's data — the app's own declared
54
+ agents, and a member's chat while they have the app open — which otherwise see only an alias,
55
+ a JS identifier that names a query without saying what it covers. Write it for whoever has to
56
+ choose between your aliases; longer guidance belongs in an agent's own `instructions`.
51
57
  - Aliases must be valid JS identifiers (`useQuery("openOrders")` and codegen depend on it).
52
58
 
53
- `lotics app deploy` syncs this map to the server. The **server holds the canonical template**;
59
+ `lotics app query set <alias>` (or `--all`) pushes this map to the server a **deploy does
60
+ not**, it echoes the live row back unchanged. The **server holds the canonical template**;
54
61
  the app never sends a raw AST over the wire. This is the exposure model: a public app can read
55
62
  exactly what its author's queries project — params fill declared value holes and can never
56
63
  widen the query's reach (a token in a `table_id` or field-key position fails deploy validation).
@@ -59,7 +66,8 @@ widen the query's reach (a token in a `table_id` or field-key position fails dep
59
66
 
60
67
  Deploy fails — with the compiler's own message, never raw SQL/Postgres text — when any alias:
61
68
 
62
- 1. isn't a valid identifier, or the declaration isn't `{ ast, params? }`;
69
+ 1. isn't a valid identifier, or the declaration isn't `{ ast, params?, description? }` (a
70
+ description over 300 characters is refused here too);
63
71
  2. references `{{params.x}}` without declaring param `x` (typos can't silently widen);
64
72
  3. doesn't parse as a `QueryNode` **as the raw template** (the runtime parses the stored
65
73
  template before substitution, so a template that only parses after substitution would fail
@@ -99,7 +107,7 @@ executes it inside a bounded transaction.
99
107
  (`private_filters`) are excluded on every reach — base scans, link extraction, and
100
108
  non-self-scoped traversals alike. (Row scopes don't apply when the app owner is an admin.)
101
109
  - **Dev loop**: `lotics app dev` forwards query RPCs to the **deployed** manifest. Editing
102
- `lotics.queries` locally does nothing until you `lotics app deploy`.
110
+ `lotics.queries` locally does nothing until you `lotics app query set`.
103
111
 
104
112
  ### Results
105
113
 
@@ -817,7 +825,8 @@ slice, and within it:
817
825
  - **B-tree-served (automatic for deployed queries):** text `equals`, number and date
818
826
  comparisons (exact and range), and `sort` fields — for fields referenced in a **deployed
819
827
  named query's template**. The platform provisions a partial expression index per referenced
820
- field automatically: built online on `app deploy` and `app query set`, re-synced daily,
828
+ field automatically: built online whenever a query is written (`app query set`, or a chat
829
+ draft's publish — a deploy does not write queries), re-synced daily,
821
830
  capped at 8 per table (fields past the cap fall back to the scan tier, with a server WARN).
822
831
  A `{{params.…}}` value hole doesn't change this — the field key is static in the template,
823
832
  so it still gets its index. Index-seek speed at any table size once provisioned.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/app-sdk",
3
- "version": "0.62.1",
3
+ "version": "0.62.3",
4
4
  "description": "Runtime SDK for Lotics custom-code apps — typed hooks, postMessage bridge, mount entry point",
5
5
  "type": "module",
6
6
  "exports": {