@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 +11 -0
- package/dist/agents/redux/execution-system/thunks/continue-agent-json.d.ts +7 -0
- package/dist/agents/redux/execution-system/thunks/continue-agent-json.js +3 -1
- package/dist/agents/redux/execution-system/thunks/run-headless-agent-json.d.ts +19 -0
- package/dist/agents/redux/execution-system/thunks/run-headless-agent-json.js +19 -7
- package/package.json +7 -7
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
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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.
|
|
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/
|
|
4684
|
+
"@ai-matrx/agents": "latest",
|
|
4685
4685
|
"@ai-matrx/associations": "latest",
|
|
4686
4686
|
"@ai-matrx/browser-audio": "latest",
|
|
4687
|
-
"@ai-matrx/
|
|
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": "
|
|
4821
|
+
"gitHead": "d9101c14c9a0338c4468cfd4c7d18aa5400a5762"
|
|
4822
4822
|
}
|