@ai-matrx/chat 0.7.16 → 0.7.17

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
@@ -1,5 +1,16 @@
1
1
  # @ai-matrx/chat
2
2
 
3
+ ## 0.7.17
4
+ ### Unreleased
5
+ ### a turn carries what the person attached (lane A1, Applet builder)
6
+
7
+ - **`runHeadlessAgentJson({ resources })`** and **`continueAgentJson({ resources })`**: the person's "+" picks (`Resource[]`) go
8
+ through THE attach path (`attachResourceToConversation`) on the turn's conversation before it executes — a stored file by its
9
+ file id (`processed_document` in request.context, then the server's `file → conversation` edge), every other kind as its typed
10
+ resource block. Never the message (THE USER-INPUT LAW). A pick that cannot be attached fails the turn naming it.
11
+ New export `attachTurnResources`. Tests: `a-turn-carries-what-the-person-attached.test.ts`.
12
+ - **Consumer action:** none (additive options).
13
+
3
14
  ## 0.7.16
4
15
 
5
16
  Automatic changed-only republish (docs/metadata drift since the last tag — see
@@ -19,6 +19,7 @@
19
19
  */
20
20
  import type { ChatDispatch, ChatRootState } from "../../../../store/root-state.js";
21
21
  import type { RequestInitiation } from "../../../types/instance.types.js";
22
+ import type { Resource } from "../../../resources/types.js";
22
23
  import { type HostTurnInput } from "./execute-instance.thunk.js";
23
24
  import { type AdoptedAgentJsonOptions, type HeadlessAgentJsonResult } from "./run-headless-agent-json.js";
24
25
  export interface ContinueAgentJsonOptions extends Pick<AdoptedAgentJsonOptions, "surfaceKey" | "timeoutMs" | "pollIntervalMs" | "settleMs" | "expect" | "onResult" | "signal" | "failureMessages"> {
@@ -29,6 +30,12 @@ export interface ContinueAgentJsonOptions extends Pick<AdoptedAgentJsonOptions,
29
30
  hostTurn?: HostTurnInput;
30
31
  /** Per-turn named context: each key is written on the instance; `null` removes it. */
31
32
  context?: Record<string, unknown>;
33
+ /**
34
+ * What the person attached, sent with THIS turn through THE attach path (see
35
+ * `HeadlessAgentJsonOptions.resources`). A file already on the conversation is an
36
+ * idempotent no-op; every other kind rides this turn again.
37
+ */
38
+ resources?: readonly Resource[];
32
39
  /** "user" when the person pressed send; "auto" for a host-started round. Default by turn kind. */
33
40
  initiation?: RequestInitiation;
34
41
  /** Fires the instant the turn's request exists (a live view binds to it). */
@@ -3,7 +3,8 @@ import { setUserInputText } from "../instance-user-input/instance-user-input.sli
3
3
  import { executeInstance } from "./execute-instance.thunk.js";
4
4
  import { loadConversation } from "./load-conversation.thunk.js";
5
5
  import {
6
- adoptHeadlessAgentJson
6
+ adoptHeadlessAgentJson,
7
+ attachTurnResources
7
8
  } from "./run-headless-agent-json.js";
8
9
  function continuationTurnProblem(opts) {
9
10
  const typed = typeof opts.userInput === "string" && opts.userInput.trim().length > 0;
@@ -25,6 +26,7 @@ async function continueAgentJson(dispatch, getState, opts) {
25
26
  for (const [key] of context.filter(([, value]) => value === null)) dispatch(removeContextEntry({ conversationId, key }));
26
27
  if (writes.length) dispatch(setContextEntries({ conversationId, entries: writes.map(([key, value]) => ({ key, value })) }));
27
28
  if (opts.userInput) dispatch(setUserInputText({ conversationId, text: opts.userInput }));
29
+ await attachTurnResources(dispatch, getState, conversationId, opts.resources);
28
30
  let requestId = null;
29
31
  const sent = await dispatch(
30
32
  executeInstance({
@@ -30,6 +30,7 @@ import type { MessagePart } from "@ai-matrx/agents/generated/stream-events";
30
30
  import type { ContextAnchor, SourceFeature, RequestInitiation } from "../../../types/instance.types.js";
31
31
  import type { ApplicationScope } from "../../../types/scope.types.js";
32
32
  import type { AnyMandateKey } from "@ai-matrx/agents/mandates";
33
+ import type { Resource } from "../../../resources/types.js";
33
34
  export interface HeadlessAgentJsonOptions {
34
35
  /** Exact agent to run. Mutually exclusive with mandateKey and shortcutId. */
35
36
  agentId?: string;
@@ -185,6 +186,17 @@ export interface HeadlessAgentJsonOptions {
185
186
  * exists once, not per call site — blocked on launcher-level attach support.
186
187
  */
187
188
  messageParts?: MessagePart[];
189
+ /**
190
+ * What the person ATTACHED for this run (files, notes, links, documents — the
191
+ * "+" picker's `Resource`s). Each goes through THE attach path
192
+ * (`attachResourceToConversation`) on the launched conversation before it
193
+ * executes: a stored file is held by its file id (`processed_document` in
194
+ * request.context until the server keeps its `file → conversation` edge), every
195
+ * other kind rides the turn as its typed resource block. Never pasted into
196
+ * `userInput` (THE USER-INPUT LAW). Forces the two-step path, like
197
+ * `messageParts`. A pick that cannot be attached fails the run, out loud.
198
+ */
199
+ resources?: readonly Resource[];
188
200
  /** Per-feature user-facing failure copy. */
189
201
  failureMessages?: {
190
202
  /** Stream errored and the request carries no usable message. */
@@ -338,3 +350,10 @@ export interface AdoptedAgentJsonOptions {
338
350
  * throws; resolves a structured result, exactly like `runHeadlessAgentJson`.
339
351
  */
340
352
  export declare function adoptHeadlessAgentJson(dispatch: ChatDispatch, getState: () => ChatRootState, opts: AdoptedAgentJsonOptions): Promise<HeadlessAgentJsonResult>;
353
+ /**
354
+ * Attach the person's picks to a conversation before its turn executes — THE attach
355
+ * path, loaded on demand (only a run that carries resources pays for it). Throws
356
+ * naming the first pick that could not be attached (the attach path has already
357
+ * said why on screen).
358
+ */
359
+ export declare function attachTurnResources(dispatch: ChatDispatch, getState: () => ChatRootState, conversationId: string, resources: readonly Resource[] | undefined): Promise<void>;
@@ -279,7 +279,7 @@ async function launchAndWait(dispatch, getState, opts) {
279
279
  const pollMs = Math.max(opts.pollIntervalMs ?? DEFAULT_POLL_MS, 100);
280
280
  const settleMs = opts.settleMs ?? DEFAULT_SETTLE_MS;
281
281
  const msgs = { ...DEFAULT_MESSAGES, ...opts.failureMessages };
282
- const twoStep = opts.messageParts !== void 0;
282
+ const twoStep = opts.messageParts !== void 0 || (opts.resources?.length ?? 0) > 0;
283
283
  let conversationId = null;
284
284
  let requestIdAnnounced = false;
285
285
  const announceRequestId = (id) => {
@@ -350,12 +350,15 @@ async function launchAndWait(dispatch, getState, opts) {
350
350
  conversationId = launch.conversationId;
351
351
  let requestId = launch.requestId;
352
352
  if (twoStep) {
353
- dispatch(
354
- setUserInputMessageParts({
355
- conversationId,
356
- parts: opts.messageParts ?? null
357
- })
358
- );
353
+ if (opts.messageParts !== void 0) {
354
+ dispatch(
355
+ setUserInputMessageParts({
356
+ conversationId,
357
+ parts: opts.messageParts ?? null
358
+ })
359
+ );
360
+ }
361
+ await attachTurnResources(dispatch, getState, conversationId, opts.resources);
359
362
  const exec = await dispatch(
360
363
  executeInstance({ conversationId, onRequestId: announceRequestId })
361
364
  ).unwrap();
@@ -592,8 +595,17 @@ function fuzzyFallback(fullResponse) {
592
595
  if (!fullResponse) return null;
593
596
  return extractFirstJson(fullResponse, { allowFuzzy: true })?.value ?? null;
594
597
  }
598
+ async function attachTurnResources(dispatch, getState, conversationId, resources) {
599
+ if (!resources?.length) return;
600
+ const { attachResourceToConversation, resourceLabel } = await import("../../../components/inputs/resources/attach-resource.js");
601
+ for (const resource of resources) {
602
+ const ok = await attachResourceToConversation({ dispatch, getState }, conversationId, resource);
603
+ if (!ok) throw new Error(`Could not attach ${resourceLabel(resource)}.`);
604
+ }
605
+ }
595
606
  export {
596
607
  adoptHeadlessAgentJson,
608
+ attachTurnResources,
597
609
  failWarnedOutputMissingKeys,
598
610
  livePosture,
599
611
  mandateOutputUnusableSentence,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/chat",
3
- "version": "0.7.16",
3
+ "version": "0.7.17",
4
4
  "description": "THE one AI Matrx person-to-agent chat system: the full chat (running agents, conversations, tool calls, streaming, context, surfaces, voice) as explicit per-module subpaths @ai-matrx/chat/<domain>/<module> (no wildcards: scripts/public-modules.json) over a host contract (/host, /host/react) whose only required value is a db. One chat, one renderer: the old kernel entries (., /external-store, /matrx, /react, /tools, styles.css, tokens.css) are retired.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -4681,15 +4681,16 @@
4681
4681
  "server-only": "^0.0.1",
4682
4682
  "uuid": "^14.0.2",
4683
4683
  "zod": "^4.6.5",
4684
- "@ai-matrx/alchemy": "latest",
4684
+ "@ai-matrx/agents": "latest",
4685
4685
  "@ai-matrx/associations": "latest",
4686
4686
  "@ai-matrx/browser-audio": "latest",
4687
- "@ai-matrx/agents": "latest",
4688
- "@ai-matrx/canvas": "latest",
4687
+ "@ai-matrx/alchemy": "latest",
4689
4688
  "@ai-matrx/content-ir": "latest",
4689
+ "@ai-matrx/canvas": "latest",
4690
+ "@ai-matrx/data": "latest",
4690
4691
  "@ai-matrx/design-system": "latest",
4692
+ "@ai-matrx/diff": "latest",
4691
4693
  "@ai-matrx/icons": "latest",
4692
- "@ai-matrx/data": "latest",
4693
4694
  "@ai-matrx/kit": "latest",
4694
4695
  "@ai-matrx/media": "latest",
4695
4696
  "@ai-matrx/print": "latest",
@@ -4698,7 +4699,6 @@
4698
4699
  "@ai-matrx/records-ui": "latest",
4699
4700
  "@ai-matrx/rich-content": "latest",
4700
4701
  "@ai-matrx/rich-editor": "latest",
4701
- "@ai-matrx/diff": "latest",
4702
4702
  "@ai-matrx/content-ir-react": "latest"
4703
4703
  },
4704
4704
  "devDependencies": {
@@ -4818,5 +4818,5 @@
4818
4818
  "check:side-effects": "node ../scripts/check-side-effects-listed.mjs . && node ../scripts/check-side-effects-listed.mjs --self-test",
4819
4819
  "check:public-surface": "node ./scripts/sync-public-surface.mjs --check && node ./scripts/sync-public-surface.mjs --self-test"
4820
4820
  },
4821
- "gitHead": "6158809f49ab5fe092f5dc6c56c60898eb0f92a6"
4821
+ "gitHead": "d9101c14c9a0338c4468cfd4c7d18aa5400a5762"
4822
4822
  }