@ykurilov/agent-chat-core 0.57.0 → 0.59.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.
@@ -1,4 +1,6 @@
1
1
  import type { ModelCatalog } from "../models/model-catalog.js";
2
+ import type { ProviderOutageKind } from "../provider-errors/provider-outages.js";
3
+ import type { ChatErrorKind } from "../conversation/types.js";
2
4
  import type { AttemptResult } from "./turn-attempt.js";
3
5
  /**
4
6
  * Запасные провайдеры той же модели (FR-030): `false` — выключены; `byModel` — свой порядок для модели или `false` для
@@ -68,7 +70,10 @@ export declare function fallbackProviders(input: {
68
70
  setting?: ProviderFallbackSetting;
69
71
  }): string[];
70
72
  /**
71
- * Переход к запасному — только при перегрузке или лимите, до первого куска ответа и один раз на ход (FR-031, FR-032).
73
+ * Кончились деньги или не принят ключ — провайдер не ответит ни на какой запрос: сразу следующий из списка, в любом
74
+ * месте хода и сколько угодно раз (список только убывает). Такой переход не тратит единственный переход по перегрузке.
75
+ * Переход к запасному при перегрузке, лимите или отказе по доступу (403: регион, модель) — до первого куска ответа и
76
+ * один раз на ход (FR-031, FR-032).
72
77
  * Переполнение — сжатие: сначала истории чата, затем первых шагов ответа, каждое не больше раза на ход (FR-012).
73
78
  * После первого куска та же перегрузка или лимит — автопродолжение у того же провайдера, до двух на ход и не при
74
79
  * запросе подтверждения (FR-037, FR-042, FR-044). Запасной после первого куска не выбирается никогда.
@@ -102,5 +107,11 @@ export declare function decideNextAttempt(result: Extract<AttemptResult, {
102
107
  nextProviderId?: string | undefined;
103
108
  };
104
109
  }): NextAttempt;
110
+ /**
111
+ * Вид ошибки для человека, когда не ответил никто. Был отказ по деньгам или ключу (`firstOutage` — первый в ходе), а
112
+ * последний провайдер лишь занят или запрос велик — его вид: «попробуйте позже» или «короче» поможет. Иначе — исходная
113
+ * причина у основного: её и чинить владельцу.
114
+ */
115
+ export declare function errorKindForPerson(lastKind: ChatErrorKind, firstOutage: ProviderOutageKind | undefined): ChatErrorKind;
105
116
  /** Проверка настройки при создании службы: неверная форма, неизвестная модель или чужой провайдер — `TypeError`. */
106
117
  export declare function checkProviderFallback(setting: ProviderFallbackSetting | undefined, catalog: ModelCatalog): void;
@@ -5,6 +5,7 @@ import type { AgentChatMessage, ChatErrorKind, FinalAnswerStatus, TokenUsage } f
5
5
  import type { AgentHelper } from "../helpers/helper-types.js";
6
6
  import type { DataChange, ScreenPlace } from "../page-context/page-context.js";
7
7
  import type { ModelCatalog, ModelProfile } from "../models/model-catalog.js";
8
+ import type { ProviderOutages } from "../provider-errors/provider-outages.js";
8
9
  import type { LongTermMemory } from "../memory/long-term-memory.js";
9
10
  import type { ModelSilenceLimits } from "../provider-errors/model-silence.js";
10
11
  import type { ChatStorage } from "../storage/chat-storage.js";
@@ -12,6 +13,7 @@ import type { CacheMissWatch } from "../usage/cache-miss-watch.js";
12
13
  import type { PendingBrowserCalls } from "./browser-tools.js";
13
14
  import type { TurnSpendingRules } from "../spending/spending-limits.js";
14
15
  import type { ModeNotes } from "./mode-notes.js";
16
+ import type { ServiceBlockFormat } from "./forged-blocks.js";
15
17
  import type { TurnReplyChecks } from "./reply-checks.js";
16
18
  import type { ProviderFallbackSetting } from "./next-attempt.js";
17
19
  import type { ResolvedSequentialTools, ToolQueue } from "./sequential-tools.js";
@@ -133,6 +135,11 @@ export interface AgentTurnInput {
133
135
  history: readonly AgentChatMessage[] | (() => Promise<readonly AgentChatMessage[]>);
134
136
  /** Вложения: что модель увидит вместо частей `file` истории. */
135
137
  attachments?: MessageAttachments;
138
+ /**
139
+ * Служебные форматы, уже проверенные: поддельный блок в ответе модели вырезается в потоке (экран, запись и следующий шаг
140
+ * его не видят), в прошлых ответах — только в запросе. Нет — форматы ядра (`CORE_SERVICE_BLOCKS`).
141
+ */
142
+ serviceBlocks?: readonly ServiceBlockFormat[];
136
143
  /** Пометки смены режима для модели; в историю не пишутся (см. `buildModelRequest`). */
137
144
  modeNotes?: ModeNotes;
138
145
  /**
@@ -279,6 +286,11 @@ export interface AgentTurnInput {
279
286
  toolResultLimit?: ResolvedToolResultLimit;
280
287
  /** Запасные провайдеры той же модели, уже проверенные. Нет — значение по умолчанию из `next-attempt`. */
281
288
  providerFallback?: ProviderFallbackSetting;
289
+ /**
290
+ * Память службы об отказах провайдеров по деньгам и ключу: основной на паузе — ход сразу у запасного. Нет — своя на
291
+ * ход: громкая строка в журнал есть, паузы между ходами нет.
292
+ */
293
+ providerOutages?: ProviderOutages;
282
294
  /** Сроки ответа серверных инструментов по имени, уже проверенные. Нет — 120 с всем. */
283
295
  toolTimeout?: ResolvedToolTimeout;
284
296
  /** Серверные инструменты, которые идут по одному (FR-049), уже проверенные. Нет — все вместе. */
@@ -1,3 +1,4 @@
1
+ import type { ServiceBlockFormat } from "../agent-run/forged-blocks.js";
1
2
  import type { AgentChatMessage } from "../conversation/types.js";
2
3
  import type { ModelProfile } from "../models/model-catalog.js";
3
4
  /** Часть `file` сообщения так, как её прислал клиент: верить в ней можно только ссылке. */
@@ -21,6 +22,8 @@ export interface MessageAttachments {
21
22
  * агента само (если приложение не добавило её раньше), чтобы вложения не приходилось подключать в двух местах.
22
23
  */
23
24
  instructions?: string;
25
+ /** Служебные форматы вложений (`<attachment>`): поддельный блок в ответе модели вырезается (`ServiceBlockFormat`). */
26
+ serviceBlocks?: readonly ServiceBlockFormat[];
24
27
  /**
25
28
  * Проверяет вложения нового сообщения (они принадлежат этому чату и этому человеку, лимиты соблюдены, срок
26
29
  * не вышел) и возвращает части для сохранения. Файлы ещё не прикреплены: сообщение может не записаться.
@@ -47,6 +47,7 @@ import type { AfterTurnHandler, AppEvent, BeforeTurnHandler, StaffActor, TurnAct
47
47
  import type { AgentWidgetSettings } from "./widgets/widget-types.js";
48
48
  import type { AgentViewerSource } from "./agent-run/agent-viewer.js";
49
49
  import type { TurnFinishedHandler } from "./agent-run/turn-finished.js";
50
+ import type { ServiceBlockFormat } from "./agent-run/forged-blocks.js";
50
51
  export { DEFAULT_TEXT_MODE_NOTE, DEFAULT_VOICE_MODE_HINT };
51
52
  /**
52
53
  * Голоса приложения для пометок модели (FR-024): чей голос сейчас у человека и какие теги этому голосу идут.
@@ -79,6 +80,12 @@ export interface AgentSettings {
79
80
  */
80
81
  helpers?: Record<string, AgentHelper>;
81
82
  maxSteps?: number;
83
+ /**
84
+ * Служебные форматы приложения и пакетов (`withSkills`, `flow.withChat`): тег `{ tag }` или строка `{ name, line }`.
85
+ * Модель, подделавшая такой блок в ответе, его не покажет: блок вырезается в потоке до экрана и записи, в прошлых
86
+ * ответах — только в запросе. Форматы ядра (`CORE_SERVICE_BLOCKS`), памяти и вложений добавляются сами.
87
+ */
88
+ serviceBlocks?: readonly ServiceBlockFormat[];
82
89
  /**
83
90
  * Пометка модели при входе в голосовой режим: добавляется один раз, отдельной текстовой частью в конец первого
84
91
  * голосового сообщения подряд. В историю чата не пишется: выводится из отметок сообщений, начало запроса от хода
@@ -385,6 +392,12 @@ export interface ChatServiceOptions {
385
392
  lockedToolOutputs?: readonly string[];
386
393
  /** События чата вне потока ответа. Нет — служба создаёт свои (`createChatServer` создаёт сам). */
387
394
  chatEvents?: ChatEvents;
395
+ /**
396
+ * Несколько служб чата на одном хранилище (своя инструкция на версию продукта и т. п.): какой службе отдать брошенную
397
+ * пачку (`answerAfterRestart`), найденную обходом этой службы (при старте, регулярно, `tickBursts`). Нет — отвечает
398
+ * сама эта служба. Задайте один и тот же `serviceFor` всем службам на этом хранилище: брошенные проверяет любая.
399
+ */
400
+ abandonedBursts?: AbandonedBurstsOptions;
388
401
  /** Фоновые задачи (пакет `@ykurilov/agent-chat-background`). Нет — запрос к модели побайтно прежний. */
389
402
  background?: BackgroundTasks;
390
403
  /**
@@ -577,6 +590,19 @@ export declare class WidgetNotPendingError extends Error {
577
590
  export declare class InvalidWidgetAnswerError extends Error {
578
591
  constructor(toolCallId: string);
579
592
  }
593
+ /** Кому отдать брошенную пачку (`ChatServiceOptions.abandonedBursts`). */
594
+ export interface AbandonedBurstsOptions {
595
+ /**
596
+ * Служба чата этой пачки: эта же, другая служба приложения или новая, созданная сейчас (`createChatService` или
597
+ * `createChatServer`). `null` — нужной службы нет: пачка никому не отдаётся и ждёт следующего обхода (через 30 с).
598
+ * Бросок — то же, со строкой в журнал. Зовётся на каждую взятую пачку, до хода; `chat` — чат из хранилища.
599
+ */
600
+ serviceFor(burst: {
601
+ ownerId: string;
602
+ chatId: string;
603
+ chat: Chat;
604
+ }): ChatService | null | undefined | Promise<ChatService | null | undefined>;
605
+ }
580
606
  /** Ответ человека на запрос подтверждения. */
581
607
  export type ApprovalAnswer = "allow" | "deny" | "always";
582
608
  /** Ответ человека на ждущий виджет. */
@@ -1,4 +1,5 @@
1
1
  import type { MessageAttachments } from "../attachments/message-attachments.js";
2
+ import type { ServiceBlockFormat } from "../agent-run/forged-blocks.js";
2
3
  import type { AgentToolsSource } from "../agent-run/run-agent-turn.js";
3
4
  import type { AgentViewerSource } from "../agent-run/agent-viewer.js";
4
5
  import type { TurnObserver } from "../agent-run/turn-observer.js";
@@ -100,6 +101,8 @@ export interface CompactionServiceOptions {
100
101
  viewer?: AgentViewerSource;
101
102
  };
102
103
  attachments?: MessageAttachments;
104
+ /** Служебные форматы хода: запрос сжатия чистит прошлые ответы так же, как ход (кэш хода). */
105
+ serviceBlocks?: readonly ServiceBlockFormat[];
103
106
  /** `null` — автосжатие выключено; записи, уже сделанные, всё равно применяются к истории. */
104
107
  settings: ResolvedCompactionSettings | null;
105
108
  logError: (message: string) => void;
@@ -1,6 +1,7 @@
1
1
  import type { ToolSet } from "ai";
2
2
  import type { ModelCallObservation } from "../agent-run/observe-model-calls.js";
3
3
  import type { MessageAttachments } from "../attachments/message-attachments.js";
4
+ import type { ServiceBlockFormat } from "../agent-run/forged-blocks.js";
4
5
  import type { AgentChatMessage, TokenUsage } from "../conversation/types.js";
5
6
  import type { ModelCatalog } from "../models/model-catalog.js";
6
7
  import type { ResolvedCompactionSettings } from "./compaction-settings.js";
@@ -31,6 +32,8 @@ export interface CompactionRunInput {
31
32
  history: readonly AgentChatMessage[];
32
33
  /** Вложения проходят тот же путь, что в обычном ходе: сводка видит текст файлов. */
33
34
  attachments?: MessageAttachments;
35
+ /** Служебные форматы хода: поддельные блоки в прошлых ответах вырезаются так же, как в ходе (кэш хода). */
36
+ serviceBlocks?: readonly ServiceBlockFormat[];
34
37
  settings: ResolvedCompactionSettings;
35
38
  /** Задание последним сообщением; по умолчанию — сводка всей переписки (`compactionTask`). */
36
39
  task?: string;
@@ -1,6 +1,7 @@
1
1
  import type { ModelMessage } from "ai";
2
2
  import type { UsageSource } from "../conversation/types.js";
3
3
  import type { ModelCatalog } from "../models/model-catalog.js";
4
+ import type { ProviderOutages } from "../provider-errors/provider-outages.js";
4
5
  import type { ModelSilenceLimits } from "../provider-errors/model-silence.js";
5
6
  import type { ChatStorage } from "../storage/chat-storage.js";
6
7
  import type { ProviderFallbackSetting } from "../agent-run/next-attempt.js";
@@ -28,6 +29,8 @@ export interface HelperRunContext {
28
29
  /** Очередь инструментов «по одному» чата: помощник делит её с основным агентом. */
29
30
  toolQueue?: ToolQueue;
30
31
  providerFallback?: ProviderFallbackSetting;
32
+ /** Память службы об отказах провайдеров по деньгам и ключу. Нет — своя на запуск. */
33
+ providerOutages?: ProviderOutages;
31
34
  modelSilence?: ModelSilenceLimits;
32
35
  turnObserver?: TurnObserver;
33
36
  /** Проверка лимита расходов перед каждым шагом; бросает `SpendingLimitReachedError`. Нет — без лимита. */
@@ -39,6 +39,8 @@ export type { OpenRouterMaxPrice, OpenRouterProviderOptions } from "./models/pro
39
39
  export { aliveAtByLocalClock, assertKnownFormatVersion, ChatAlreadyExistsError, DuplicateChatSubjectError, DuplicateMessageError, MessageAlreadyFinishedError, MessageNotAwaitingError, RELEASED_ANSWER_ALIVE_AT, sameMessageParts, silenceBoundaryByLocalClock, UnsupportedFormatVersionError, } from "./storage/chat-storage.js";
40
40
  export { assertChatData, assertChatDataFilter, CHAT_DATA_MAX_BYTES, ChatDataTooLargeError, chatDataFields, chatDataMatches, chatDataOfInput, mergeChatData } from "./storage/chat-data.js";
41
41
  export type { ChatDataFilter, ChatDataFilterValue } from "./storage/chat-data.js";
42
+ export { migratePostgresSchema } from "./storage/postgres-migrations.js";
43
+ export type { PostgresMigrationConnection, PostgresMigrationOptions } from "./storage/postgres-migrations.js";
42
44
  export type { AwaitingMessagePatch, ChatListOptions, ChatStorage, ChatSubjectFilter, FinishedMessagePatch, ImportedChat, MessageLink, MessagePartsLink, NewChatInput, SpendingLimitStateRecord, StoredPendingBurst, StreamingMessagePatch, } from "./storage/chat-storage.js";
43
45
  export { SpendingLimitReachedError } from "./spending/spending-limits.js";
44
46
  export { APP_EVENT_DATA_MAX_BYTES, APP_EVENT_TYPE_MAX_LENGTH, isTurnRefusalCode, normalizeTurnRefusal, TURN_REFUSAL_MESSAGE_MAX_LENGTH, TurnRefusedError, validateAppEvent, } from "./turn-hooks/turn-hooks.js";
@@ -69,7 +71,7 @@ export { createInMemoryChatStorage } from "./storage/in-memory-storage.js";
69
71
  export { ChatBusyError, createRunningAnswerRegistry } from "./running-answers/running-answer-registry.js";
70
72
  export type { RunningAnswerRegistry } from "./running-answers/running-answer-registry.js";
71
73
  export { ChatNotFoundError, createChatService, InvalidMessageError, InvalidModelChoiceError, NothingToRetryError, } from "./chat-service.js";
72
- export type { ActionOptions, AgentSettings, ChatBranchForks, ChatCompactions, ChatHistory, ChatListItem, ChatService, ChatInstructions, ChatInstructionsTurn, ChatState, CompactionMarker, CompactionOutcome, CompactionSettings, FlushOptions, CheckReplyInput, CheckReplyResult, IncomingUserMessage, ModelChoice, ModelChosenHandler, ModelMenu, RecoverInterruptedAnswersOptions, SendMessageOptions, SendBurstOptions, BurstMessageResult, SteerResult, } from "./chat-service.js";
74
+ export type { AbandonedBurstsOptions, ActionOptions, AgentSettings, ChatBranchForks, ChatCompactions, ChatHistory, ChatListItem, ChatService, ChatInstructions, ChatInstructionsTurn, ChatState, CompactionMarker, CompactionOutcome, CompactionSettings, FlushOptions, CheckReplyInput, CheckReplyResult, IncomingUserMessage, ModelChoice, ModelChosenHandler, ModelMenu, RecoverInterruptedAnswersOptions, SendMessageOptions, SendBurstOptions, BurstMessageResult, SteerResult, } from "./chat-service.js";
73
75
  export { STEER_PART_TYPE, isCorrection } from "./steering/turn-steering.js";
74
76
  export { BURST_HOLD_MS, BURST_PART_TYPE, BURST_SWEEP_LIMIT, DEFAULT_BURST_QUIET_MS, isBurstMessage } from "./bursts/message-bursts.js";
75
77
  export { GREETING_LEAD } from "./agent-run/greeting-lead.js";
@@ -94,6 +96,8 @@ export type { MaxOutputTokensSetting, TurnTimeoutSetting } from "./agent-run/tur
94
96
  export type { SequentialToolsSetting } from "./agent-run/sequential-tools.js";
95
97
  export type { ModelCallEvent, ModelCallPurpose, ToolCallEvent, TurnObserver } from "./agent-run/turn-observer.js";
96
98
  export type { TurnFinished, TurnFinishedHandler } from "./agent-run/turn-finished.js";
99
+ export { CORE_SERVICE_BLOCKS, checkServiceBlockFormats, cutForgedBlocks, serviceBlockName } from "./agent-run/forged-blocks.js";
100
+ export type { ServiceBlockFormat } from "./agent-run/forged-blocks.js";
97
101
  export { DEFAULT_MODEL_SILENCE } from "./provider-errors/model-silence.js";
98
102
  export type { ModelSilenceLimits, ModelSilenceSetting } from "./provider-errors/model-silence.js";
99
103
  export { APP_CHANGE_PART_TYPE, BROWSER_CALL_PART_TYPE } from "./page-context/page-context.js";
@@ -1,3 +1,4 @@
1
+ import type { ServiceBlockFormat } from "../agent-run/forged-blocks.js";
1
2
  import type { LanguageModel, ToolSet } from "ai";
2
3
  import type { AgentToolsModel } from "../agent-run/run-agent-turn.js";
3
4
  import type { TokenUsage } from "../conversation/types.js";
@@ -49,6 +50,8 @@ export interface LongTermMemory {
49
50
  * ядро откажет при создании службы. Если инструменты заданы функцией, повтор ловится при сборке набора хода.
50
51
  */
51
52
  toolNames: readonly string[];
53
+ /** Служебные форматы памяти (`<agent_memory>`): поддельный блок в ответе модели вырезается (`ServiceBlockFormat`). */
54
+ serviceBlocks?: readonly ServiceBlockFormat[];
52
55
  /**
53
56
  * Блок памяти для вопроса хода или `null`, если записей нет. Зовётся один раз на чат: в первом ходе и после сжатия
54
57
  * истории; в идущем чате блок берётся из прошлого ответа.
@@ -6,3 +6,8 @@ import type { ProviderDescription } from "../models/model-catalog.js";
6
6
  * Порядок общий с тихими повторами: «не повторять» → переполнение → «повторять».
7
7
  */
8
8
  export declare function classifyProviderError(error: unknown, provider?: Pick<ProviderDescription, "errorHints">): ChatErrorKind;
9
+ /**
10
+ * Провайдер отказал по доступу (403 без слов о ключе и деньгах): регион, доступ к модели. Другой провайдер может
11
+ * ответить. Модерация — не такой отказ: дело в содержимом, и другому провайдеру оно не передаётся.
12
+ */
13
+ export declare function isAccessRefusal(error: unknown): boolean;
@@ -1,6 +1,6 @@
1
1
  /** Запрос не влез в окно модели: признаки в тексте или код 413. Признаки лимита запросов — не переполнение. */
2
2
  export declare function isContextOverflow(text: string, statusCode?: number): boolean;
3
- /** Квота, бюджет или оплата исчерпаны: повторять не нужно. */
4
- export declare function isNotRetryable(text: string): boolean;
3
+ /** Квота, бюджет или оплата исчерпаны: повторять не нужно. При коде 429 — только явные признаки пустого счёта. */
4
+ export declare function isNotRetryable(text: string, statusCode?: number): boolean;
5
5
  /** Текст похож на временный сбой провайдера или сети. */
6
6
  export declare function looksTransient(text: string): boolean;
@@ -0,0 +1,41 @@
1
+ import type { ChatErrorKind } from "../conversation/types.js";
2
+ /** Отказ, после которого провайдер не ответит ни на какой запрос: кончились деньги или не принят ключ. */
3
+ export type ProviderOutageKind = Extract<ChatErrorKind, "insufficient_funds" | "invalid_key">;
4
+ export declare function isProviderOutage(kind: ChatErrorKind): kind is ProviderOutageKind;
5
+ /** Сколько провайдер на паузе после отказа: новые ходы это время сразу идут к запасному. */
6
+ export declare const PROVIDER_OUTAGE_PAUSE_MS: number;
7
+ /** Громкая строка о провайдере — не чаще. */
8
+ export declare const PROVIDER_OUTAGE_ALERT_EVERY_MS: number;
9
+ /** Пауза кончилась: один ход пробует провайдера, остальные это время идут мимо. Проба без итога — через этот срок следующая. */
10
+ export declare const PROVIDER_OUTAGE_PROBE_MS = 60000;
11
+ /**
12
+ * Память службы об отказах провайдеров по деньгам и ключу. Пустой счёт за минуты не пополнится: ходы на паузе не
13
+ * стучат в него каждый раз, а после паузы его пробует один ход, не все разом. Кэш при этом не теряется — ответить
14
+ * основной всё равно не может, а запасной на паузе получает все запросы подряд, и его кэш тёплый.
15
+ */
16
+ export interface ProviderOutages {
17
+ /**
18
+ * Провайдер отказал: пауза на `PROVIDER_OUTAGE_PAUSE_MS` и, не чаще раза в `PROVIDER_OUTAGE_ALERT_EVERY_MS`, строка
19
+ * `[ВНИМАНИЕ провайдер]` в журнал. `fallbackProviderId` — кто отвечает вместо; нет — ходы падают, а
20
+ * `fallbacksPaused` говорит, что запасные есть, но тоже на паузе.
21
+ */
22
+ report(input: {
23
+ providerId: string;
24
+ kind: ProviderOutageKind;
25
+ fallbackProviderId?: string;
26
+ fallbacksPaused?: boolean;
27
+ }): void;
28
+ /** Вид отказа, пока провайдер на паузе или его пробует другой ход; иначе `undefined`. Ничего не меняет. */
29
+ pausedKind(providerId: string): ProviderOutageKind | undefined;
30
+ /**
31
+ * Ход хочет к провайдеру: `undefined` — можно, вид отказа — нельзя. Пауза кончилась — первый получает пробу
32
+ * на `PROVIDER_OUTAGE_PROBE_MS`, остальные до её итога — вид отказа.
33
+ */
34
+ admit(providerId: string): ProviderOutageKind | undefined;
35
+ /** Провайдер ответил: пауза снята. Счёт громких строк остаётся — «мигающий» провайдер не шумит. */
36
+ recovered(providerId: string): void;
37
+ }
38
+ export declare function createProviderOutages(options: {
39
+ now: () => number;
40
+ logError: (message: string) => void;
41
+ }): ProviderOutages;
@@ -0,0 +1,28 @@
1
+ /** Соединение PostgreSQL, которое нужно помощнику миграций. Подходит `PoolClient` из `pg`: core от `pg` не зависит. */
2
+ export interface PostgresMigrationConnection {
3
+ query(text: string, values?: unknown[]): Promise<{
4
+ rows: unknown[];
5
+ }>;
6
+ release(): void;
7
+ }
8
+ export interface PostgresMigrationOptions<Connection extends PostgresMigrationConnection> {
9
+ /** Новое соединение из пула, например `() => pool.connect()`; на каждую попытку — своё. */
10
+ connect(): Promise<Connection>;
11
+ /** Своя блокировка пакета: одновременно мигрирует только одна копия этого пакета. */
12
+ lockKey: number;
13
+ /** Миграции пакета на этом соединении, например `migrate(drizzle(connection), …)`. */
14
+ migrate(connection: Connection): Promise<void>;
15
+ /** Паузы перед повторами, если всё же столкнулись с соседом. */
16
+ retryDelaysMs?: readonly number[];
17
+ }
18
+ /** Схема всех пакетов SDK. */
19
+ export declare const AGENT_CHAT_SCHEMA = "agent_chat";
20
+ /** Общая блокировка на создание схемы: одна на все пакеты, держится только на `create schema`. */
21
+ export declare const AGENT_CHAT_SCHEMA_LOCK_KEY = 7311900441;
22
+ /**
23
+ * Создаёт схему `agent_chat` и применяет миграции пакета так, чтобы пакеты могли стартовать одновременно на пустой базе.
24
+ * Схема создаётся под общей блокировкой, затем она отпускается и берётся своя блокировка пакета: блокировки не
25
+ * вложены, поэтому взаимной блокировки нет, а разные пакеты ждут друг друга только на создании схемы.
26
+ * Столкнулись всё же («уже есть») — повтор с начала на новом соединении.
27
+ */
28
+ export declare function migratePostgresSchema<Connection extends PostgresMigrationConnection>(options: PostgresMigrationOptions<Connection>): Promise<void>;
@@ -0,0 +1,6 @@
1
+ /** Ограда блока кода в начале строки (``` или ~~~, не дальше трёх пробелов от края) или `null`. */
2
+ export declare function codeFenceOf(line: string): string | null;
3
+ /** Строка закрывает блок кода, открытый оградой `fence`: та же ограда не короче, и больше ничего в строке. */
4
+ export declare function closesCodeFence(line: string, fence: string): boolean;
5
+ /** Строка — код с отступом (4 пробела или табуляция) или цитата (`> …`). */
6
+ export declare function isIndentedCodeOrQuote(line: string): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ykurilov/agent-chat-core",
3
- "version": "0.57.0",
3
+ "version": "0.59.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "sideEffects": false,