@ykurilov/agent-chat-flows 0.76.0 → 0.77.0

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/dist/react.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  FLOW_DEADLINE_NOTICE,
4
4
  FLOW_TIMER_NOTICE,
5
5
  fieldValueText
6
- } from "./chunk-DQQ2GCQ2.js";
6
+ } from "./chunk-CZ3EDVYW.js";
7
7
  import {
8
8
  ANY_STATE_LAYOUT_KEY,
9
9
  DEFAULT_LATE_START_HOURS,
@@ -31,7 +31,7 @@ import {
31
31
  startRun,
32
32
  stateById,
33
33
  timerDueAt
34
- } from "./chunk-2LAVG3YR.js";
34
+ } from "./chunk-RMWVLMGY.js";
35
35
 
36
36
  // src/react/flow-labels.ts
37
37
  import { createContext, createElement, useContext } from "react";
@@ -0,0 +1,35 @@
1
+ /** Ссылка на проверку, зарегистрированную сервером приложения, а не моделью или JSON сценария. */
2
+ export interface FlowConfirmationRef {
3
+ key: string;
4
+ revision: string;
5
+ }
6
+ export interface FlowConfirmationScope {
7
+ ownerId: string;
8
+ chatId: string;
9
+ flowId: string;
10
+ }
11
+ export interface FlowConfirmationReceipt extends FlowConfirmationRef {
12
+ status: "confirmed";
13
+ scope: FlowConfirmationScope;
14
+ criterionHash: string;
15
+ checkedAt: number;
16
+ source: {
17
+ kind: "judge";
18
+ versionId: string;
19
+ answerId: string;
20
+ humanMessageId: string;
21
+ probability: number;
22
+ };
23
+ }
24
+ /** Tombstone: прежнее доказательство не используется для повторного подтверждения после исправления. */
25
+ export interface FlowConfirmationRevocation extends FlowConfirmationRef {
26
+ status: "revoked";
27
+ versionId: string;
28
+ scope: FlowConfirmationScope;
29
+ criterionHash: string;
30
+ revokedAt: number;
31
+ afterMessageId: string | null;
32
+ reason: string;
33
+ operationKey: string;
34
+ }
35
+ export type FlowConfirmationRecord = FlowConfirmationReceipt | FlowConfirmationRevocation;
@@ -1,3 +1,4 @@
1
+ import type { FlowConfirmationRecord, FlowConfirmationRef } from "./confirmation.js";
1
2
  /** Ключ в состоянии чата (`ChatState`), под которым лежит `FlowRun`. */
2
3
  export declare const FLOW_STATE_KEY = "flow";
3
4
  /** Сколько последних шагов пути хранить в чате. */
@@ -31,6 +32,22 @@ export interface FlowPathEntry {
31
32
  }
32
33
  /** Где чат в сценарии. Хранится в состоянии чата под `FLOW_STATE_KEY`; все времена — мс с 1970 года. */
33
34
  export interface FlowRun {
35
+ /** Проверки сервера: на этой ветке, для этого человека/чата/сценария. Модель их не устанавливает. */
36
+ confirmations?: Record<string, FlowConfirmationRecord>;
37
+ /** Идемпотентность полного afterTurn check; отрицательный результат не переносится на следующий human turn. */
38
+ confirmationCheck?: {
39
+ answerId: string;
40
+ configurationHash: string;
41
+ };
42
+ /** Receipt и решение сохраняются одной записью до применения перехода. */
43
+ checkedTransition?: {
44
+ versionId: string;
45
+ transition: Transition;
46
+ requires: FlowConfirmationRef;
47
+ criterionHash: string;
48
+ answerId: string;
49
+ humanMessageId: string;
50
+ };
34
51
  state: string;
35
52
  /** Когда вошли в текущее состояние. */
36
53
  enteredAt: number;
@@ -1,4 +1,5 @@
1
1
  export * from "./flow-run.js";
2
+ export type * from "./confirmation.js";
2
3
  export { nextTransition, type FlowEvent } from "./next-transition.js";
3
4
  export { startRun, applyTransition, noteHumanMessage, noteAgentAnswer, noteRejectedClaim, claimAllowed, noteSideQuestion, } from "./run-updates.js";
4
5
  export { dataConditionHolds, fieldValueFits } from "./data-conditions.js";
@@ -0,0 +1,26 @@
1
+ import { type TurnResult } from "@ykurilov/agent-chat-core";
2
+ import type { FlowRun, Transition } from "../engine/flow-run.js";
3
+ import { type FlowConfirmations } from "./confirmations.js";
4
+ import type { FlowJudge, FlowPort, JudgeMessage } from "./flow-types.js";
5
+ import type { PinnedFlow } from "./flow-events.js";
6
+ /** Положительный check и guarded decision — одна служебная запись до исполнения перехода. */
7
+ export declare function judgeConfirmations(input: {
8
+ confirmations: FlowConfirmations;
9
+ pinned: PinnedFlow;
10
+ run: FlowRun;
11
+ result: TurnResult;
12
+ port: FlowPort;
13
+ atMessageId: string | null;
14
+ judge: FlowJudge;
15
+ threshold: number;
16
+ now: number;
17
+ conditions: Array<{
18
+ exitId: string;
19
+ text: string;
20
+ }>;
21
+ messages: JudgeMessage[];
22
+ goal?: string;
23
+ }): Promise<{
24
+ transition?: Transition;
25
+ saved: boolean;
26
+ }>;
@@ -0,0 +1,12 @@
1
+ import type { FlowStore } from "../store/flow-store.js";
2
+ import type { AgentFlowHandle, FlowPort } from "./flow-types.js";
3
+ import { type FlowConfirmations } from "./confirmations.js";
4
+ /** Strict preview читает исходный run до map. Legacy path/card не являются квитанцией SDK. */
5
+ export declare function previewConfirmedMigration(input: Parameters<AgentFlowHandle["previewMigration"]>[0], deps: {
6
+ store: FlowStore;
7
+ confirmations: FlowConfirmations;
8
+ portFor: (chat: {
9
+ ownerId: string;
10
+ chatId: string;
11
+ }) => Promise<FlowPort>;
12
+ }): ReturnType<AgentFlowHandle["previewMigration"]>;
@@ -0,0 +1,40 @@
1
+ import type { FlowConfirmationRecord, FlowConfirmationRef, FlowConfirmationScope } from "../engine/confirmation.js";
2
+ import type { FlowRun } from "../engine/flow-run.js";
3
+ import type { AgentFlow } from "../format/flow-format.js";
4
+ /** Server-only: условие проверяется независимо от выхода и сохраняется только после положительного judge. */
5
+ export interface FlowConfirmationSpec extends FlowConfirmationRef {
6
+ flowId: string;
7
+ states: readonly string[];
8
+ judge: string;
9
+ }
10
+ /** Серверный guard одного judge-выхода. Свежий интерес не превращается в durable флаг. */
11
+ export interface FlowExitGuard {
12
+ flowId: string;
13
+ state: string;
14
+ exitId: string;
15
+ requires: FlowConfirmationRef;
16
+ judgeWindow: "current-human-turn";
17
+ }
18
+ export declare const confirmationHash: (spec: FlowConfirmationSpec) => string;
19
+ export declare function confirmationHolds(record: FlowConfirmationRecord | undefined, spec: FlowConfirmationSpec, scope: FlowConfirmationScope): boolean;
20
+ /** Настройка фиксируется на сервере. Отсутствующая/устаревшая revision означает unknown. */
21
+ export declare function createConfirmations(specs?: readonly FlowConfirmationSpec[], guards?: readonly FlowExitGuard[]): {
22
+ validate(flowId: string, flow: AgentFlow): void;
23
+ forState: (flowId: string, state: string) => FlowConfirmationSpec[];
24
+ specFor: (flowId: string, ref: FlowConfirmationRef) => FlowConfirmationSpec | undefined;
25
+ guardFor: (flowId: string, state: string, exitId: string) => FlowExitGuard | undefined;
26
+ revision: (flowId: string) => string;
27
+ allows(scope: FlowConfirmationScope, run: FlowRun, exitId: string): boolean;
28
+ };
29
+ export type FlowConfirmations = ReturnType<typeof createConfirmations>;
30
+ export interface FlowRevokeConfirmationInput extends FlowConfirmationRef, FlowConfirmationScope {
31
+ expectedAtMessageId: string | null;
32
+ idempotencyKey: string;
33
+ reason: string;
34
+ }
35
+ export type FlowRevokeConfirmationResult = {
36
+ status: "applied" | "same";
37
+ atMessageId: string;
38
+ } | {
39
+ status: "stale" | "busy" | "not_found";
40
+ };
@@ -24,6 +24,7 @@ export interface PinnedFlow {
24
24
  }
25
25
  /** Что общего у частей сценария в службе чата: хранилище, часы, сценарий чата и отчёт о переходах. */
26
26
  export interface FlowRuntime {
27
+ confirmations?: import("./confirmations.js").FlowConfirmations;
27
28
  store: FlowStore;
28
29
  now(): number;
29
30
  logError(message: string): void;
@@ -537,6 +537,8 @@ export interface ChatsByStateOptions extends FlowChatSelection {
537
537
  exceptVersionId?: string;
538
538
  }
539
539
  export interface MigrateChatsInput extends FlowChatSelection {
540
+ /** Strict: без подходящего SDK receipt чат остаётся на исходной immutable версии. */
541
+ requiresConfirmation?: import("../engine/confirmation.js").FlowConfirmationRef;
540
542
  flowId: string;
541
543
  toVersionId: string;
542
544
  /** Куда перевести чаты из состояний, которых нет в новой версии: id старого → id нового. */
@@ -580,6 +582,9 @@ export interface FlowChatOptions {
580
582
  appNoticeViews?: AppNoticeViews;
581
583
  }
582
584
  export interface AgentFlowOptions {
585
+ /** Серверные подтверждения. Не поля карточки, не инструменты записи фактов и не JSON редактора. */
586
+ confirmations?: readonly import("./confirmations.js").FlowConfirmationSpec[];
587
+ exitGuards?: readonly import("./confirmations.js").FlowExitGuard[];
583
588
  /** Какой сценарий у чата; `null` — чат без сценария. Зовётся, пока чат не закреплён за версией. */
584
589
  loadFlow: (input: {
585
590
  ownerId: string;
@@ -628,6 +633,19 @@ export interface FlowSignalInput {
628
633
  wakeAgent?: boolean;
629
634
  }
630
635
  export interface AgentFlowHandle {
636
+ /** Read-only strict preview. Старый path/card/currentState не восстанавливают proof. */
637
+ previewMigration(input: Pick<MigrateChatsInput, "flowId" | "toVersionId" | "requiresConfirmation" | "chatIds" | "filter" | "includeEnded" | "includeTestChats"> & {
638
+ requiresConfirmation: import("../engine/confirmation.js").FlowConfirmationRef;
639
+ }): Promise<{
640
+ eligible: string[];
641
+ keepOriginal: Array<{
642
+ chatId: string;
643
+ status: "ambiguous";
644
+ reason: string;
645
+ }>;
646
+ }>;
647
+ /** Только доверенный backend: исправление атрибуции. busy/stale требуют обработки приложением. */
648
+ revokeConfirmation(input: import("./confirmations.js").FlowRevokeConfirmationInput): Promise<import("./confirmations.js").FlowRevokeConfirmationResult>;
631
649
  /** Склеивает сценарий с настройками службы чата: инструкция, инструменты, блоки, `prepareTurn`, `afterTurn`. */
632
650
  withChat<T extends FlowChatOptions>(options: T): T;
633
651
  /** Служба чата (`attach(service)`, как в 0.48) или служба на чат и своя доставка. */
@@ -1,4 +1,6 @@
1
1
  export { createAgentFlow } from "./agent-flow.js";
2
+ export type { FlowConfirmationSpec, FlowExitGuard, FlowRevokeConfirmationInput, FlowRevokeConfirmationResult } from "./confirmations.js";
3
+ export type * from "../engine/confirmation.js";
2
4
  export { FLOW_SERVICE_BLOCKS } from "./flow-service-blocks.js";
3
5
  export type * from "./flow-types.js";
4
6
  export { DEFAULT_JUDGE_MODEL, DEFAULT_JUDGE_THRESHOLD, DEFAULT_JUDGE_TIMEOUT_MS } from "./judge.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ykurilov/agent-chat-flows",
3
- "version": "0.76.0",
3
+ "version": "0.77.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -56,13 +56,13 @@
56
56
  "ai": "7.0.122",
57
57
  "drizzle-orm": "^0.45.3",
58
58
  "zod": "^4.6.5",
59
- "@ykurilov/agent-chat-core": "0.76.0"
59
+ "@ykurilov/agent-chat-core": "0.77.0"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "better-sqlite3": "^13.0.3",
63
63
  "pg": "^8.23.0",
64
64
  "react": "^19.3.0",
65
- "@ykurilov/agent-chat-react": "^0.76.0"
65
+ "@ykurilov/agent-chat-react": "^0.77.0"
66
66
  },
67
67
  "peerDependenciesMeta": {
68
68
  "@ykurilov/agent-chat-react": {
@@ -90,7 +90,7 @@
90
90
  "pg": "^8.23.0",
91
91
  "react": "^19.3.0",
92
92
  "tsx": "4.23.15",
93
- "@ykurilov/agent-chat-react": "0.76.0"
93
+ "@ykurilov/agent-chat-react": "0.77.0"
94
94
  },
95
95
  "scripts": {
96
96
  "build": "node ../../scripts/build-package.mjs",