@cxtms/cx-schema 1.9.261 → 1.9.262

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cxtms/cx-schema",
3
- "version": "1.9.261",
3
+ "version": "1.9.262",
4
4
  "description": "Schema validation package for CXTMS YAML modules",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -10807,6 +10807,70 @@ scalar TimeSpanScalar
10807
10807
 
10808
10808
  scalar UUID @specifiedBy(url: "https://tools.ietf.org/html/rfc4122")
10809
10809
 
10810
+ scalar Long
10811
+
10812
+ extend type Query {
10813
+ quickSearch(organizationId: Int!, query: String!, entityNames: [String!], take: Int! = 5): QuickSearchResult!
10814
+ quickSearchEntities(organizationId: Int!): [QuickSearchEntity!]!
10815
+ agentSessionAttachments(skip: Int, take: Int, organizationId: Int!, agentSessionId: UUID, contentKind: AttachmentContentKind): AgentSessionAttachmentsCollectionSegment @cost(weight: "10")
10816
+ }
10817
+
10818
+ type QuickSearchResult {
10819
+ groups: [QuickSearchGroup!]!
10820
+ }
10821
+
10822
+ type QuickSearchGroup {
10823
+ entityName: String!
10824
+ items: [QuickSearchItem!]!
10825
+ total: Int!
10826
+ hasMore: Boolean!
10827
+ partial: Boolean!
10828
+ }
10829
+
10830
+ type QuickSearchItem {
10831
+ key: String!
10832
+ matchRank: Int!
10833
+ data: MapOfObject
10834
+ }
10835
+
10836
+ type QuickSearchEntity {
10837
+ entityName: String!
10838
+ entityKind: String!
10839
+ groupLabel: MapOfObject
10840
+ icon: String!
10841
+ order: Int!
10842
+ display: MapOfObject
10843
+ open: MapOfObject
10844
+ }
10845
+
10846
+ type AgentSessionAttachmentGqlDto {
10847
+ attachmentId: Int!
10848
+ fileName: String!
10849
+ contentType: String
10850
+ size: Long
10851
+ origin: AgentSessionAttachmentOrigin!
10852
+ createdAt: DateTime!
10853
+ agentSessionId: UUID!
10854
+ sessionTitle: String
10855
+ workflowId: UUID!
10856
+ }
10857
+
10858
+ type AgentSessionAttachmentsCollectionSegment {
10859
+ pageInfo: CollectionSegmentInfo!
10860
+ items: [AgentSessionAttachmentGqlDto!]
10861
+ totalCount: Int! @cost(weight: "10")
10862
+ }
10863
+
10864
+ enum AttachmentContentKind {
10865
+ Image
10866
+ Document
10867
+ }
10868
+
10869
+ enum AgentSessionAttachmentOrigin {
10870
+ Uploaded
10871
+ Produced
10872
+ }
10873
+
10810
10874
  extend type Query {
10811
10875
  dispatchRouteStopStatus(
10812
10876
  organizationId: Int!
@@ -38,6 +38,14 @@ Order quick search (`orders.search` and `orderGroupBy.search`) matches order num
38
38
 
39
39
  Order-move quick search (`orderMoves.search`) matches the move name plus its owning order's tracking number and JSON custom values (for example, a container number). Matching is case-insensitive and accepts partial text.
40
40
 
41
+ ## Cross-entity quick search
42
+
43
+ `quickSearchEntities(organizationId)` returns the organization's searchable entity configuration: entity name/kind, localized group label, icon and ordering, display templates, and the route or dialog used to open a result. Load this configuration before rendering a search palette.
44
+
45
+ `quickSearch(organizationId, query, entityNames?, take: 5)` searches all configured entities or an optional subset. Results are grouped by `entityName`; each group includes `total`, `hasMore`, `partial`, and ranked items with a stable string `key` and `data` map. Apply the matching entity configuration's display and open templates to `data`.
46
+
47
+ `agentSessionAttachments(organizationId, agentSessionId?, contentKind?, skip?, take?)` lists attachments from agent sessions visible to the caller. Omit the session id for an all-visible-sessions library; filter `contentKind` by `Image` or `Document`. Each item identifies its attachment, source session/workflow, file metadata, and whether its `origin` is `Uploaded` or `Produced`.
48
+
41
49
  ## App Module Metadata Visibility
42
50
 
43
51
  GraphQL metadata queries hide rows attached to soft-deleted app modules:
@@ -12,6 +12,7 @@
12
12
  - Tool approval (`tools[].mode`) and the chat's Ask/Auto approval mode
13
13
  - Built-in data tools (`tools[].builtin`): `data.query`, `data.schema`, `data.type`
14
14
  - History compression
15
+ - Files in chat: what the model receives, and the model config's `supportsFiles` flag
15
16
  - Session ownership and live events
16
17
  - Triggers: synchronous execution and lock behavior for trigger-bound agents
17
18
  - The `ai.default` organization config shape
@@ -212,6 +213,41 @@ Each chat turn adds to a growing conversation history, bounded by the model's co
212
213
  - On the client side, the internal Responses route announces a compression with a `response.tms.history_compressed` stream event; the transcript (GraphQL) always shows the `summary` message and a `usage` entry with `kind: "summary"`, on both routes.
213
214
  - If an agent frequently needs long conversations against a small model, either raise `model.contextWindow` to match the model actually in use (see the property table above) or keep `agent.instructions` terse so more of the window is available for turns.
214
215
 
216
+ ## Files in Chat
217
+
218
+ People can attach files to a chat message in the AI Assistant: up to 5 per message, 25 MB each, of these types:
219
+
220
+ | Kind | Types | What the model receives |
221
+ |---|---|---|
222
+ | Documents | PDF | The file itself: inline bytes up to 4 MB, above that a presigned URL (PDF URLs only for the `anthropic` provider — other providers refuse a PDF over 4 MB) |
223
+ | Images | PNG, JPG/JPEG | The image: inline bytes up to 4 MB, above that a presigned URL |
224
+ | Text | TXT, CSV, JSON, MD | The text, decoded as UTF-8 and cut at 200,000 characters with a truncation note |
225
+
226
+ Nothing in `agent:` YAML opts in or out — every chat agent accepts files, and there is no YAML schema change. What
227
+ the agent sees:
228
+
229
+ - Each file arrives in the user's turn after a label such as `[Attached file: bol.pdf (PDF, 1.2 MB)]`, so the model
230
+ can refer to it by name. Text content is fenced as data, not instructions — like a tool result — so a file that
231
+ says "ignore your instructions" is just text in a file.
232
+ - Files stay in the conversation: every later turn can still read them (they are re-sent on each model call, within a
233
+ 16 MB inline budget per call; older files beyond it go by URL or as a note asking the user to attach them again).
234
+ When history is compressed, the summary names the files but their content leaves the history.
235
+ - A file that can't be read when a turn runs reaches the model as `[File <name> could not be read.]` instead of
236
+ failing the turn.
237
+ - Every chat upload becomes an Attachment linked to the session (parent type `AgentSession`, category
238
+ `AgentSession`), visible only to people who can see the chat, and listed in the AI Assistant's Library. Task
239
+ sessions (workflow runs) never receive files.
240
+
241
+ **Which models read PDFs and images** is decided by the model config's `supportsFiles` flag (see
242
+ [The `ai.default` Organization Config](#the-aidefault-organization-config)). When it is `false`, the chat refuses PDFs
243
+ and images when they are attached — before the message is sent — and text files still work. `GET .../ai/models`
244
+ reports it per agent as `supports_files`, which the chat uses to validate a file before uploading it.
245
+
246
+ Write `agent.instructions` for chat agents that will receive documents to say what to do with them (e.g. "When the
247
+ user attaches a bill of lading, read the shipper, consignee and pallet count from it"), and to answer only from
248
+ what the file shows. Full request shapes and error messages are in `docs/agent-api.md` §4 "Attaching files" in
249
+ `tms-backend-api`.
250
+
215
251
  ## Session Ownership and Live Events
216
252
 
217
253
  Every agent session (task or chat) has an owner scope — `User`, `Division`, or `Organization` — that governs who may see it, continue it, decide its approvals, and watch it live. A chat session defaults to `User` (its starter); a task session defaults to `Organization` (it has no starter). Ownership can be changed afterward (e.g. shared with a division) via a GraphQL mutation, and every session change publishes a live event.
@@ -237,10 +273,16 @@ For a trigger-bound agent, either:
237
273
  "model": "claude-sonnet-4-5",
238
274
  "apiKey": "...",
239
275
  "endpoint": "https://api.anthropic.com",
240
- "contextWindow": 200000
276
+ "contextWindow": 200000,
277
+ "supportsFiles": true
241
278
  }
242
279
  ```
243
280
 
281
+ `supportsFiles` (optional) says whether the model reads PDFs and images attached in chat (see
282
+ [Files in chat](#files-in-chat)). When it is absent, it defaults to `true` for the `anthropic` and `openai`
283
+ providers and to `false` for any other provider. Set it to `false` for a model without vision or PDF support, and
284
+ to `true` for a file-capable model behind another provider. Text attachments work either way.
285
+
244
286
  Set up this config once per organization (or per named config for `model.fromConfig` overrides); every Agent workflow that doesn't override `model.name`/`model.temperature` shares it. The config's own `contextWindow` (if set) is the fallback used when the agent's YAML doesn't declare `model.contextWindow` — but only while the agent doesn't also override `model.name`; overriding the model name without also setting `agent.model.contextWindow` falls straight through to the runtime default of 256,000 tokens, since the config's window describes the config's model, not the override.
245
287
 
246
288
  ## Tool Name Derivation (Workflow Name → Tool Name)
@@ -257,6 +299,7 @@ When a workflow is exposed as a tool (via another agent's `tools[].workflow`, or
257
299
  - **Use `mode: always` for actions a person must confirm every time.** `approval` tools run unattended once a user switches the chat to Auto; `always` tools never do.
258
300
  - **Give chat agents `agent.ui`.** A `shortDescription`, an `icon`, a `color` and a few `prompts` make the agent recognizable in the AI Assistant's agent menu and empty state.
259
301
  - **Set `model.contextWindow` whenever you set `model.name`.** Otherwise a smaller model than the org default silently gets the 256K default window, and history compression won't kick in until it's already over budget (or a larger model gets compressed too eagerly). See the `model.contextWindow` row above.
302
+ - **Set `supportsFiles` on the model config to match the model.** A model that can't read PDFs or images should say so (`"supportsFiles": false`), so the chat refuses those files up front instead of the provider failing the turn. See [Files in chat](#files-in-chat).
260
303
  - **Design `agent.result`/`agent.instructions` around whichever session type(s) the agent is actually used in.** A chat-only agent doesn't need `agent.result` (it has no `set_result` tool); a task-only agent should tell the model explicitly to call `set_result` exactly once (the scaffolded template's instructions already do this).
261
304
  - **Keep trigger-bound agents fast**, or move them off the triggering request entirely (see [Triggers](#triggers)) — a slow agent session holds the entity's workflow lock for its whole duration.
262
305