@rsconcept/rstool 1.4.3 → 1.6.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/README.md +5 -4
- package/dist/{agent-workflow-D22FeODL.d.ts → agent-workflow-BTwrxOoX.d.ts} +9 -2
- package/dist/{diagnostic-assembly-DRunIcKQ.js → diagnostic-assembly-B-6vIA5I.js} +3 -1
- package/dist/{diagnostic-assembly-DRunIcKQ.js.map → diagnostic-assembly-B-6vIA5I.js.map} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/mappers/model-adapter.js +127 -1
- package/dist/mappers/model-adapter.js.map +1 -0
- package/dist/mappers/schema-adapter.d.ts +5 -1
- package/dist/mappers/schema-adapter.js +44 -11
- package/dist/mappers/schema-adapter.js.map +1 -1
- package/dist/mappers/types.js +1 -1
- package/dist/models/agent-workflow.d.ts +2 -2
- package/dist/models/diagnostic.js +1 -1
- package/dist/models/index.d.ts +4 -4
- package/dist/models/index.js +1 -1
- package/dist/models/rstool-agent.d.ts +1 -1
- package/dist/models/rstool-agent.js +1 -1
- package/dist/models/tool-contract.d.ts +1 -1
- package/dist/models/tool-contract.js +1 -1
- package/dist/models/tool-contract.js.map +1 -1
- package/dist/{models-B255GaEC.js → models-LMyDB0md.js} +25 -4
- package/dist/models-LMyDB0md.js.map +1 -0
- package/dist/rsform-builder-DKwZfJvN.js +102 -0
- package/dist/rsform-builder-DKwZfJvN.js.map +1 -0
- package/dist/{rstool-agent-BGQAzFly.d.ts → rstool-agent-BrAFJcoE.d.ts} +6 -4
- package/dist/session/session-store.js +1 -1
- package/dist/{tool-contract-sQfr-DYD.d.ts → tool-contract-BUaDRHoO.d.ts} +8 -3
- package/dist/wrapper/stdio-wrapper.js +8 -2
- package/dist/wrapper/stdio-wrapper.js.map +1 -1
- package/docs/CONCEPTUAL-SCHEMA.md +44 -0
- package/docs/CONSTITUENTA.md +1 -1
- package/docs/DIAGNOSTICS.md +32 -31
- package/docs/README.md +3 -3
- package/package.json +19 -18
- package/skills/README.md +3 -3
- package/skills/rstool-helper/EXAMPLES.md +194 -3
- package/skills/rstool-helper/GUIDE.md +79 -8
- package/skills/rstool-helper/REFERENCE.md +192 -34
- package/skills/rstool-helper/SKILL.md +28 -8
- package/src/mappers/diagnostic-assembly.ts +3 -0
- package/src/mappers/rsform-builder.ts +1 -1
- package/src/mappers/schema-adapter.ts +48 -16
- package/src/models/agent-workflow.ts +8 -0
- package/src/models/index.ts +1 -0
- package/src/models/rstool-agent.test.ts +21 -0
- package/src/models/rstool-agent.ts +23 -0
- package/src/models/tool-contract.ts +8 -1
- package/src/wrapper/stdio-handler.ts +8 -1
- package/dist/model-adapter-D-YmIvQW.js +0 -225
- package/dist/model-adapter-D-YmIvQW.js.map +0 -1
- package/dist/models-B255GaEC.js.map +0 -1
|
@@ -1,34 +1,68 @@
|
|
|
1
1
|
# ЯРЭ и rstool — справочник
|
|
2
2
|
|
|
3
|
+
Контракт library / stdio / MCP для агентов. Воркфлоу — [GUIDE.md](GUIDE.md). Примеры — [EXAMPLES.md](EXAMPLES.md). Язык — `docs/*.md`.
|
|
4
|
+
|
|
3
5
|
## Контракт rstool
|
|
4
6
|
|
|
5
7
|
- Пакет: `@rsconcept/rstool`
|
|
6
|
-
- Версия контракта: `3.
|
|
8
|
+
- Версия контракта: `3.1.0` (`CONTRACT_VERSION`)
|
|
7
9
|
- Основной класс: `RSToolAgent`
|
|
8
10
|
- Публичные импорты: `@rsconcept/rstool` и `@rsconcept/rstool/wrapper`
|
|
11
|
+
- Опции: `new RSToolAgent({ persistenceDir? })` — каталог для сохранения сессий между перезапусками (stdio/MCP: `RSTOOL_PERSISTENCE_DIR`)
|
|
12
|
+
|
|
13
|
+
Почти все методы принимают optional `sessionId` вторым аргументом (в stdio/MCP — поле `sessionId` в плоских `params`). Без него используется текущая сессия; при необходимости сессия создаётся лениво.
|
|
9
14
|
|
|
10
15
|
### Методы library API
|
|
11
16
|
|
|
12
|
-
| Метод | Назначение
|
|
13
|
-
| ---------------------------------------------- |
|
|
14
|
-
| `ensureSession(initial?)` | Вернуть текущую сессию или создать новую
|
|
15
|
-
| `createSession(initial?)` | Новая in-memory сессия
|
|
16
|
-
| `getCurrentSession()` | Текущая активная сессия или `null`
|
|
17
|
-
| `setCurrentSession(sessionId)` | Сделать сессию текущей
|
|
18
|
-
| `applySchemaPatch(input, sessionId?)` | Единственный путь правки схемы
|
|
19
|
-
| `getSessionState(detail?, sessionId?)` | `summary` (default) или `full`
|
|
20
|
-
| `listDiagnostics(filters?, sessionId?)` | Активные диагностики
|
|
21
|
-
| `analyzeExpression(input, sessionId?)` | Разбор без сохранения
|
|
22
|
-
| `commitStep(message?, sessionId?)` | Ревизия
|
|
23
|
-
| `exportSession(sessionId?)` | JSON сессии
|
|
24
|
-
| `exportPortal({ kind, format? }, sessionId?)` | Portal Load from JSON
|
|
25
|
-
| `importData(payload, kind?)` | Импорт сессии / Portal
|
|
26
|
-
| `setModelValues({ set?, clear? }, sessionId?)` | Значения модели (async —
|
|
27
|
-
| `getModelState(sessionId?)` | Состояние интерпретации
|
|
28
|
-
| `evaluate(input, sessionId?)` | Scratch или конституента
|
|
29
|
-
| `recalculateModel(sessionId?)` | Пересчёт
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
| Метод | Назначение |
|
|
18
|
+
| ---------------------------------------------- | ------------------------------------------- |
|
|
19
|
+
| `ensureSession(initial?)` | Вернуть текущую сессию или создать новую |
|
|
20
|
+
| `createSession(initial?)` | Новая in-memory сессия (становится текущей) |
|
|
21
|
+
| `getCurrentSession()` | Текущая активная сессия или `null` |
|
|
22
|
+
| `setCurrentSession(sessionId)` | Сделать сессию текущей |
|
|
23
|
+
| `applySchemaPatch(input, sessionId?)` | Единственный путь правки схемы |
|
|
24
|
+
| `getSessionState(detail?, sessionId?)` | `summary` (default) или `full` |
|
|
25
|
+
| `listDiagnostics(filters?, sessionId?)` | Активные диагностики |
|
|
26
|
+
| `analyzeExpression(input, sessionId?)` | Разбор без сохранения |
|
|
27
|
+
| `commitStep(message?, sessionId?)` | Ревизия |
|
|
28
|
+
| `exportSession(sessionId?)` | JSON-строка сессии |
|
|
29
|
+
| `exportPortal({ kind, format? }, sessionId?)` | Portal Load from JSON |
|
|
30
|
+
| `importData(payload, kind?)` | Импорт сессии / Portal |
|
|
31
|
+
| `setModelValues({ set?, clear? }, sessionId?)` | Значения модели (**async** — `await`) |
|
|
32
|
+
| `getModelState(sessionId?)` | Состояние интерпретации |
|
|
33
|
+
| `evaluate(input, sessionId?)` | Scratch или конституента |
|
|
34
|
+
| `recalculateModel(sessionId?)` | Пересчёт производных |
|
|
35
|
+
| `restoreOrder(sessionId?)` | Упорядочить конституенты (топология + семантика) |
|
|
36
|
+
|
|
37
|
+
Служебные (stdio / MCP): `ping` / `pong`+`contractVersion`; `methods` / `list_methods`.
|
|
38
|
+
|
|
39
|
+
### Library ↔ stdio ↔ MCP
|
|
40
|
+
|
|
41
|
+
Stdio использует **camelCase** имён методов (как library). MCP (`@rsconcept/rstool-mcp`) — **snake_case**. Params везде **плоские** (без обёртки `input`).
|
|
42
|
+
|
|
43
|
+
| Library / stdio | MCP tool |
|
|
44
|
+
| ------------------- | --------------------- |
|
|
45
|
+
| `ping` | `ping` |
|
|
46
|
+
| `methods` | `list_methods` |
|
|
47
|
+
| `ensureSession` | `ensure_session` |
|
|
48
|
+
| `createSession` | `create_session` |
|
|
49
|
+
| `getCurrentSession` | `get_current_session` |
|
|
50
|
+
| `setCurrentSession` | `set_current_session` |
|
|
51
|
+
| `applySchemaPatch` | `apply_schema_patch` |
|
|
52
|
+
| `getSessionState` | `get_session_state` |
|
|
53
|
+
| `listDiagnostics` | `list_diagnostics` |
|
|
54
|
+
| `analyzeExpression` | `analyze_expression` |
|
|
55
|
+
| `commitStep` | `commit_step` |
|
|
56
|
+
| `exportSession` | `export_session` |
|
|
57
|
+
| `exportPortal` | `export_portal` |
|
|
58
|
+
| `importData` | `import_data` |
|
|
59
|
+
| `setModelValues` | `set_model_values` |
|
|
60
|
+
| `getModelState` | `get_model_state` |
|
|
61
|
+
| `evaluate` | `evaluate` |
|
|
62
|
+
| `recalculateModel` | `recalculate_model` |
|
|
63
|
+
| `restoreOrder` | `restore_order` |
|
|
64
|
+
|
|
65
|
+
## `applySchemaPatch`
|
|
32
66
|
|
|
33
67
|
```ts
|
|
34
68
|
tool.applySchemaPatch({
|
|
@@ -38,23 +72,132 @@ tool.applySchemaPatch({
|
|
|
38
72
|
});
|
|
39
73
|
```
|
|
40
74
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
75
|
+
**Вход**
|
|
76
|
+
|
|
77
|
+
| Поле | Смысл |
|
|
78
|
+
| ---------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
79
|
+
| `items` | Массив патчей; у каждого обязателен `alias` |
|
|
80
|
+
| `initial?` | `alias` / `title` / `comment` — только если для patch создаётся новая сессия |
|
|
81
|
+
| `mode?` | `'atomic'` (default) — откат всей пачки при первой ошибке; `'best_effort'` — применяются корректные элементы |
|
|
82
|
+
| `commitMessage?` | После успешного patch фиксирует ревизию |
|
|
83
|
+
|
|
84
|
+
**Патч элемента:** `alias` обязателен; `id`, `cstType`, `definitionFormal`, `term`, `definitionText`, `convention` опциональны. `id` и `cstType` выводятся из префикса `alias` (`X/C/S/D/F/P/A/T/N`). Поля мержатся с существующей конституентой.
|
|
85
|
+
|
|
86
|
+
**Поведение:** `items` упорядочиваются автоматически (поставщики раньше потребителей).
|
|
87
|
+
|
|
88
|
+
**Результат:** `{ success, applied, failed, diagnostics, session, summary, revision? }`.
|
|
89
|
+
|
|
90
|
+
- `applied` — успешно применённые конституенты со `analysis`.
|
|
91
|
+
- `failed` — `{ draft, diagnostics }[]` (при `best_effort` или атомарном отказе).
|
|
92
|
+
- `summary` — компактный обзор сессии (см. ниже).
|
|
93
|
+
- `revision` — если был `commitMessage`.
|
|
94
|
+
|
|
95
|
+
Для крупных импортов с частичными ошибками формул предпочитай `mode: 'best_effort'`, затем правь оставшееся по `failed` / `listDiagnostics`.
|
|
96
|
+
|
|
97
|
+
## `getSessionState`
|
|
98
|
+
|
|
99
|
+
- `getSessionState()` / `getSessionState('summary')` → `SessionSummary`:
|
|
100
|
+
- `sessionId`, `contractVersion`, `alias`, `title`, `comment`
|
|
101
|
+
- `itemCount`, `modelItemCount`, `diagnosticsCount`
|
|
102
|
+
- `items[]`: `{ id, alias, cstType, analysisSuccess }`
|
|
103
|
+
- `diagnostics[]` (активные)
|
|
104
|
+
- `lastRevision?`
|
|
105
|
+
- `getSessionState('full')` → полный `SessionState` (все конституенты с формулами, модель, ревизии). Для обзора агенту обычно хватает `summary`.
|
|
106
|
+
|
|
107
|
+
## `listDiagnostics`
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
tool.listDiagnostics();
|
|
111
|
+
tool.listDiagnostics({ kind: 'expression' });
|
|
112
|
+
tool.listDiagnostics({ kind: 'schema', constituentId: 3, severity: 'error' });
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Фильтры: `kind?: 'expression' | 'schema' | 'model'`, `constituentId?`, `severity?: 'error' | 'warning'`.
|
|
116
|
+
|
|
117
|
+
Элемент диагностики (агентский вид): `kind`, `code`, `name`, `severity`, `alias?`, `expression`, `from`, `to`, `params?`. Ключ для поиска исправления — `name` ([DIAGNOSTICS.md](../../docs/DIAGNOSTICS.md)).
|
|
118
|
+
|
|
119
|
+
## `analyzeExpression`
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
tool.analyzeExpression({
|
|
123
|
+
expression: 'Pr1(S1)',
|
|
124
|
+
cstType: CstType.TERM,
|
|
125
|
+
recordDiagnostics: false // default
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Вход:** `expression`, `cstType` (обязательны); `recordDiagnostics?` — писать ли диагностики в сессию (default `false`).
|
|
130
|
+
|
|
131
|
+
**Результат:** `{ success, type, valueClass, diagnostics }`. Не сохраняет конституенту. Для черновика формулы — до `applySchemaPatch`.
|
|
132
|
+
|
|
133
|
+
## `evaluate`
|
|
134
|
+
|
|
135
|
+
Ровно один вариант входа:
|
|
136
|
+
|
|
137
|
+
- конституента: `{ constituentId }`
|
|
138
|
+
- scratch: `{ expression, cstType }`
|
|
139
|
+
|
|
140
|
+
**Результат:** `{ success, value, status, iterations, cacheHits, diagnostics }`.
|
|
141
|
+
|
|
142
|
+
`status` — статус вычисления КМ (`HAS_DATA`, `EMPTY`, `AXIOM_FALSE`, `EVAL_FAIL`, … — [DOMAIN.md](../../docs/DOMAIN.md)).
|
|
143
|
+
|
|
144
|
+
## `setModelValues` / `getModelState` / `recalculateModel`
|
|
145
|
+
|
|
146
|
+
```ts
|
|
147
|
+
await tool.setModelValues({
|
|
148
|
+
set: [{ target: 1, value: { 0: 'a', 1: 'b' } }],
|
|
149
|
+
clear: [3]
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
- `set[]`: `{ target, value, type? }` — `target` = id конституенты; `type` обычно не нужен.
|
|
154
|
+
- `clear[]`: id для сброса значений.
|
|
155
|
+
- Метод **async**. После изменения данных пересчитываются диагностики модели.
|
|
156
|
+
- `getModelState()` → `{ items: [{ id, type, value }] }`.
|
|
157
|
+
- `recalculateModel()` → `{ items: [{ id, alias, value, status }] }`.
|
|
158
|
+
|
|
159
|
+
Формы `value` для `X#` / `S#` — [MODEL-TESTING.md](../../docs/MODEL-TESTING.md).
|
|
160
|
+
|
|
161
|
+
## `restoreOrder`
|
|
162
|
+
|
|
163
|
+
Упорядочивает конституенты сессии одним проходом Kahn:
|
|
164
|
+
|
|
165
|
+
- формальные зависимости — жёстко (поставщик раньше зависимого);
|
|
166
|
+
- семантические дети — сразу после родителя, если уже готовы;
|
|
167
|
+
- иначе — стабильно относительно приоритета типов/ядра.
|
|
168
|
+
|
|
169
|
+
```ts
|
|
170
|
+
const { orderedAliases } = tool.restoreOrder();
|
|
171
|
+
// → { orderedIds: number[], orderedAliases: string[] }
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## `importData` / `exportSession` / `exportPortal`
|
|
45
175
|
|
|
46
176
|
### `importData(payload, kind?)`
|
|
47
177
|
|
|
48
|
-
`kind`: `'auto'` (default
|
|
178
|
+
`kind`: `'auto'` (default), `'session'`, `'portal-details'` (`GET /api/rsforms/:id/details`), `'portal-schema'` (Portal Load from JSON). После импорта новая сессия становится текущей. Возвращает `SessionHandle`.
|
|
49
179
|
|
|
50
|
-
|
|
180
|
+
Portal JSON из `/details` **не** является `exportSession` — не передавай его с `kind: 'session'`.
|
|
51
181
|
|
|
52
|
-
|
|
182
|
+
### `exportSession()`
|
|
53
183
|
|
|
54
|
-
|
|
184
|
+
JSON-строка сессии для последующего `importData(..., 'session')`.
|
|
55
185
|
|
|
56
|
-
|
|
57
|
-
|
|
186
|
+
### `exportPortal({ kind, format? })`
|
|
187
|
+
|
|
188
|
+
- `kind`: `'schema'` | `'model'`
|
|
189
|
+
- `format?`: `'json'` (default, строка) | `'object'`
|
|
190
|
+
- Для загрузки в Portal UI: обычно `exportPortal({ kind: 'schema' })`.
|
|
191
|
+
|
|
192
|
+
## `commitStep` / сессии
|
|
193
|
+
|
|
194
|
+
- `commitStep(message?)` → `{ revisionId, at, message? }`.
|
|
195
|
+
- `ensureSession` / `createSession` принимают optional `initial`: `alias`, `title`, `comment` (и прочие поля `SessionState` в library).
|
|
196
|
+
- `SessionHandle`: `{ sessionId, contractVersion }`.
|
|
197
|
+
|
|
198
|
+
## Протокол stdio
|
|
199
|
+
|
|
200
|
+
Плоские `params`. Переменная окружения `RSTOOL_PERSISTENCE_DIR` — каталог персистентности.
|
|
58
201
|
|
|
59
202
|
```json
|
|
60
203
|
{"id":"2","method":"applySchemaPatch","params":{"items":[{"alias":"X1"}]}}
|
|
@@ -62,8 +205,23 @@ tool.applySchemaPatch({
|
|
|
62
205
|
{"id":"8","method":"evaluate","params":{"constituentId":3}}
|
|
63
206
|
{"id":"9","method":"exportPortal","params":{"kind":"schema"}}
|
|
64
207
|
{"id":"10","method":"importData","params":{"payload":"..."}}
|
|
208
|
+
{"id":"11","method":"getSessionState","params":{"detail":"summary"}}
|
|
65
209
|
```
|
|
66
210
|
|
|
67
|
-
##
|
|
68
|
-
|
|
69
|
-
|
|
211
|
+
## Help map: ошибка → документ
|
|
212
|
+
|
|
213
|
+
| Ситуация | Куда |
|
|
214
|
+
| -------------------------------------------------- | ------------------------------------------------------- |
|
|
215
|
+
| Код / `name` диагностики | [DIAGNOSTICS.md](../../docs/DIAGNOSTICS.md) |
|
|
216
|
+
| Синтаксис операторов, `D{}`/`I{}`/`R{}`, `F#`/`P#` | [SYNTAX.md](../../docs/SYNTAX.md) |
|
|
217
|
+
| Ступени, `AnalysisResult.type` | [TYPIFICATION.md](../../docs/TYPIFICATION.md) |
|
|
218
|
+
| `X#` vs `C#` vs `Z`, переносимость | [BASE-SELECTION.md](../../docs/BASE-SELECTION.md) |
|
|
219
|
+
| Проектирование, `F#` vs пары, ревью | [CONCEPTUAL-SCHEMA.md](../../docs/CONCEPTUAL-SCHEMA.md) |
|
|
220
|
+
| Поля и валидация конституенты | [CONSTITUENTA.md](../../docs/CONSTITUENTA.md) |
|
|
221
|
+
| Формы значений КМ, тесты | [MODEL-TESTING.md](../../docs/MODEL-TESTING.md) |
|
|
222
|
+
| Ссылка Portal, REST, curl | [PORTAL-API.md](../../docs/PORTAL-API.md) |
|
|
223
|
+
| Термины, статусы, «не путать» | [DOMAIN.md](../../docs/DOMAIN.md) |
|
|
224
|
+
| Воркфлоу агента | [GUIDE.md](GUIDE.md) |
|
|
225
|
+
| Сниппеты и антипаттерны | [EXAMPLES.md](EXAMPLES.md) |
|
|
226
|
+
|
|
227
|
+
Исходники кодов ошибок ЯРЭ: `@rsconcept/domain` (`RSErrorCode`, `error.ts`). Не дублируй грамматику в skill — правь domain и при необходимости этот help map.
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rstool-helper
|
|
3
3
|
description: >-
|
|
4
|
-
ЯРЭ
|
|
4
|
+
ЯРЭ и концептуальные схемы через rstool: концептуализация, ревью/оценка КС,
|
|
5
|
+
правки и диагностики формул, проверка на КМ (evaluate), выбор X#/C#/Z,
|
|
6
|
+
импорт/экспорт Portal (/rsforms, /details). Читай GUIDE и docs из node_modules.
|
|
5
7
|
---
|
|
6
8
|
|
|
7
9
|
# rstool-helper
|
|
@@ -16,15 +18,32 @@ description: >-
|
|
|
16
18
|
|
|
17
19
|
Затем продолжай с каноническими файлами ниже.
|
|
18
20
|
|
|
19
|
-
## Канонические файлы
|
|
21
|
+
## Канонические файлы
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
- API, stdio, контракт: `node_modules/@rsconcept/rstool/skills/rstool-helper/REFERENCE.md`
|
|
23
|
-
- Примеры, типичные ошибки: `node_modules/@rsconcept/rstool/skills/rstool-helper/EXAMPLES.md`
|
|
24
|
-
- Язык и предметная область: `node_modules/@rsconcept/rstool/docs/*.md`
|
|
25
|
-
- Процедура установки: `node_modules/@rsconcept/rstool/skills/INSTALL.md`
|
|
23
|
+
Префикс путей: `node_modules/@rsconcept/rstool/`.
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
| Что | Путь |
|
|
26
|
+
| :-------------------------------------------------- | :---------------------------------- |
|
|
27
|
+
| **Начни здесь** — матрица задач, воркфлоу, чеклисты | `skills/rstool-helper/GUIDE.md` |
|
|
28
|
+
| API, stdio, MCP, контракт | `skills/rstool-helper/REFERENCE.md` |
|
|
29
|
+
| Примеры, антипаттерны | `skills/rstool-helper/EXAMPLES.md` |
|
|
30
|
+
| Язык и предметная область | `docs/*.md` |
|
|
31
|
+
| Установка skill | `skills/INSTALL.md` |
|
|
32
|
+
|
|
33
|
+
## Задача → что читать
|
|
34
|
+
|
|
35
|
+
Не читай все `docs/` подряд. Открой **GUIDE.md** (раздел «Задача → чтение»), затем только нужные файлы:
|
|
36
|
+
|
|
37
|
+
| Задача | Минимум |
|
|
38
|
+
| :-------------------------------- | :----------------------------------------------------------------------------- |
|
|
39
|
+
| Собрать / развить КС из текста | GUIDE: концептуализация; `docs/CONCEPTUAL-SCHEMA.md`; `docs/BASE-SELECTION.md` |
|
|
40
|
+
| Оценить / отревьюить готовую КС | GUIDE: ревью; чеклист ревью; `docs/CONCEPTUAL-SCHEMA.md` |
|
|
41
|
+
| Починить формулу / диагностики | GUIDE: цикл диагностик; `docs/DIAGNOSTICS.md` |
|
|
42
|
+
| Импорт / правка по ссылке Portal | GUIDE: Portal; `docs/PORTAL-API.md` |
|
|
43
|
+
| Проверить смысл на данных | GUIDE: КМ; `docs/MODEL-TESTING.md` |
|
|
44
|
+
| Синтаксис / типизация / вызов API | `docs/SYNTAX.md` / `TYPIFICATION.md` / `REFERENCE.md` |
|
|
45
|
+
|
|
46
|
+
Перед работой всегда открой **GUIDE.md**; остальное — по строке таблицы.
|
|
28
47
|
|
|
29
48
|
## Не правь пакет rstool без запроса
|
|
30
49
|
|
|
@@ -41,4 +60,5 @@ REST API и curl — `node_modules/@rsconcept/rstool/docs/PORTAL-API.md`.
|
|
|
41
60
|
## Кратко
|
|
42
61
|
|
|
43
62
|
- Пакет: `@rsconcept/rstool`; обёртка: `npx rstool-wrapper`
|
|
63
|
+
- MCP: `@rsconcept/rstool-mcp` (имена tools — `snake_case`, см. REFERENCE)
|
|
44
64
|
- `@rsconcept/domain` устанавливается как зависимость (анализатор и коды ошибок)
|
|
@@ -90,6 +90,9 @@ function expressionForCstDiagnostic(cst: Constituenta, diagnostic: CstDiagnostic
|
|
|
90
90
|
return cst.convention;
|
|
91
91
|
case RSDiagnosticCode.schemaTypeMismatch:
|
|
92
92
|
return cst.typification_manual;
|
|
93
|
+
case RSDiagnosticCode.schemaDependencyCycle:
|
|
94
|
+
case RSDiagnosticCode.schemaFormalDuplicate:
|
|
95
|
+
return cst.definition_formal;
|
|
93
96
|
default:
|
|
94
97
|
return cst.definition_formal;
|
|
95
98
|
}
|
|
@@ -75,7 +75,7 @@ export function enrichSessionConstituents(session: SessionState): EnrichedConsti
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
assignSchemaDiagnostics(schema.items, resolveAlias, normalizedDefinitions);
|
|
78
|
+
assignSchemaDiagnostics(schema.items, resolveAlias, normalizedDefinitions, schema.graph);
|
|
79
79
|
|
|
80
80
|
return session.items.map(item => ({
|
|
81
81
|
item,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { RSLangAnalyzer, type AnalysisFull, type ValueClass } from '@rsconcept/domain/rslang';
|
|
2
1
|
import { getAnalysisFor } from '@rsconcept/domain/library/rsform-api';
|
|
3
|
-
import {
|
|
2
|
+
import { type RSForm } from '@rsconcept/domain/library/rsform';
|
|
3
|
+
import { RSLangAnalyzer } from '@rsconcept/domain/rslang';
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
type AnalysisResult,
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type Diagnostic,
|
|
10
10
|
type SessionState
|
|
11
11
|
} from '../models';
|
|
12
|
+
import { buildRSFormFromSession } from './rsform-builder';
|
|
12
13
|
import { toPublicAnalysis } from './types';
|
|
13
14
|
|
|
14
15
|
export class SchemaAdapter {
|
|
@@ -16,9 +17,8 @@ export class SchemaAdapter {
|
|
|
16
17
|
session: SessionState,
|
|
17
18
|
draft: ConstituentaDraft
|
|
18
19
|
): { result: AnalysisResult; diagnostics: Diagnostic[] } {
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const analysis = getAnalysisFor(draft.definitionFormal, draft.cstType, schema as unknown as RSForm, draft.alias);
|
|
20
|
+
const schema = this.toAnalysisSchema(session, draft);
|
|
21
|
+
const analysis = getAnalysisFor(draft.definitionFormal, draft.cstType, schema, draft.alias);
|
|
22
22
|
const target = { constituentId: draft.id, alias: draft.alias };
|
|
23
23
|
const result = toPublicAnalysis(
|
|
24
24
|
{
|
|
@@ -70,18 +70,50 @@ export class SchemaAdapter {
|
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Schema view for analysis: session items with the draft expression merged in so the
|
|
75
|
+
* dependency graph (and cycle diagnostics) reflect the expression under check.
|
|
76
|
+
*/
|
|
77
|
+
private toAnalysisSchema(session: SessionState, draft: ConstituentaDraft): RSForm {
|
|
78
|
+
const items = session.items.map(item => {
|
|
79
|
+
if (item.id !== draft.id) {
|
|
80
|
+
return item;
|
|
78
81
|
}
|
|
79
|
-
|
|
80
|
-
item
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
return {
|
|
83
|
+
...item,
|
|
84
|
+
alias: draft.alias,
|
|
85
|
+
cstType: draft.cstType,
|
|
86
|
+
definitionFormal: draft.definitionFormal,
|
|
87
|
+
term: draft.term ?? item.term,
|
|
88
|
+
definitionText: draft.definitionText ?? item.definitionText,
|
|
89
|
+
convention: draft.convention ?? item.convention,
|
|
90
|
+
// Drop cached type so mutual references surface as untyped → cycle.
|
|
91
|
+
analysis: {
|
|
92
|
+
...item.analysis,
|
|
93
|
+
success: false,
|
|
94
|
+
type: null,
|
|
95
|
+
valueClass: null
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
if (!items.some(item => item.id === draft.id)) {
|
|
100
|
+
items.push({
|
|
101
|
+
id: draft.id,
|
|
102
|
+
alias: draft.alias,
|
|
103
|
+
cstType: draft.cstType,
|
|
104
|
+
definitionFormal: draft.definitionFormal,
|
|
105
|
+
term: draft.term ?? '',
|
|
106
|
+
definitionText: draft.definitionText ?? '',
|
|
107
|
+
convention: draft.convention ?? '',
|
|
108
|
+
analysis: {
|
|
109
|
+
success: false,
|
|
110
|
+
type: null,
|
|
111
|
+
valueClass: null,
|
|
112
|
+
diagnostics: []
|
|
113
|
+
}
|
|
114
|
+
});
|
|
84
115
|
}
|
|
85
|
-
|
|
116
|
+
|
|
117
|
+
return buildRSFormFromSession({ ...session, items });
|
|
86
118
|
}
|
|
87
119
|
}
|
|
@@ -35,6 +35,14 @@ export interface ApplySchemaPatchInput {
|
|
|
35
35
|
commitMessage?: string;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/** Result of {@link RSToolAgent.restoreOrder}. */
|
|
39
|
+
export interface RestoreOrderResult {
|
|
40
|
+
/** Constituent ids in the restored declaration order. */
|
|
41
|
+
orderedIds: number[];
|
|
42
|
+
/** Aliases in the same order as {@link orderedIds}. */
|
|
43
|
+
orderedAliases: string[];
|
|
44
|
+
}
|
|
45
|
+
|
|
38
46
|
/** Compact view of one constituent in a session summary. */
|
|
39
47
|
export interface SessionSummaryItem {
|
|
40
48
|
id: number;
|
package/src/models/index.ts
CHANGED
|
@@ -877,6 +877,27 @@ describe('RSToolAgent import and export', () => {
|
|
|
877
877
|
expect(exported.items.map(item => item.alias)).toEqual(['D1', 'S1', 'C1', 'X1']);
|
|
878
878
|
});
|
|
879
879
|
|
|
880
|
+
it('restoreOrder reorders by formal topology and kernel priority', () => {
|
|
881
|
+
const tool = new RSToolAgent();
|
|
882
|
+
const session = tool.createSession({ title: 'Restore', alias: 'RO' });
|
|
883
|
+
tool.applySchemaPatch(
|
|
884
|
+
{
|
|
885
|
+
items: [
|
|
886
|
+
{ alias: 'D1', cstType: CstType.TERM, definitionFormal: 'Pr1(S1)\\X1' },
|
|
887
|
+
{ alias: 'S1', cstType: CstType.STRUCTURED, definitionFormal: 'ℬ(X1×X1)' },
|
|
888
|
+
{ alias: 'A2', cstType: CstType.AXIOM, definitionFormal: 'P1[S1]' },
|
|
889
|
+
{ alias: 'P1', cstType: CstType.PREDICATE, definitionFormal: '[α∈ℬ(R1)] card(α)=0' },
|
|
890
|
+
{ alias: 'X1', cstType: CstType.BASE, definitionFormal: '' }
|
|
891
|
+
]
|
|
892
|
+
},
|
|
893
|
+
session.sessionId
|
|
894
|
+
);
|
|
895
|
+
|
|
896
|
+
const result = tool.restoreOrder(session.sessionId);
|
|
897
|
+
expect(result.orderedAliases.slice(0, 5)).toEqual(['X1', 'P1', 'S1', 'A2', 'D1']);
|
|
898
|
+
expect(fullState(tool, session.sessionId).items.map(item => item.alias)).toEqual(result.orderedAliases);
|
|
899
|
+
});
|
|
900
|
+
|
|
880
901
|
it('round-trips portal schema export and import', () => {
|
|
881
902
|
const tool = new RSToolAgent();
|
|
882
903
|
const session = tool.createSession({ title: 'Round trip', alias: 'RT' });
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { restoreConstituentOrder } from '@rsconcept/domain/library/rsform-api';
|
|
1
2
|
import {
|
|
2
3
|
portalDetailsToDrafts,
|
|
3
4
|
portalDetailsToSessionSeed,
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
type AgentConstituentaPatch,
|
|
14
15
|
type ApplySchemaPatchInput,
|
|
15
16
|
type ApplySchemaPatchResult,
|
|
17
|
+
type RestoreOrderResult,
|
|
16
18
|
type SessionStateDetail,
|
|
17
19
|
type SessionStateResult,
|
|
18
20
|
type SessionSummary
|
|
@@ -303,6 +305,27 @@ export class RSToolAgent implements RSToolAgentContract {
|
|
|
303
305
|
return result;
|
|
304
306
|
}
|
|
305
307
|
|
|
308
|
+
/** @inheritdoc */
|
|
309
|
+
public restoreOrder(sessionId?: string): RestoreOrderResult {
|
|
310
|
+
const id = this.resolveSessionId(sessionId);
|
|
311
|
+
const envelope = this.sessions.get(id);
|
|
312
|
+
const orderable = envelope.state.items.map(item => ({
|
|
313
|
+
id: item.id,
|
|
314
|
+
alias: item.alias,
|
|
315
|
+
cst_type: item.cstType,
|
|
316
|
+
definition_formal: item.definitionFormal
|
|
317
|
+
}));
|
|
318
|
+
const ordered = restoreConstituentOrder(orderable);
|
|
319
|
+
const byId = new Map(envelope.state.items.map(item => [item.id, item]));
|
|
320
|
+
envelope.state.items = ordered.map(item => byId.get(item.id)!);
|
|
321
|
+
envelope.state.updatedAt = new Date().toISOString();
|
|
322
|
+
this.sessions.replaceState(id, envelope.state);
|
|
323
|
+
return {
|
|
324
|
+
orderedIds: ordered.map(item => item.id),
|
|
325
|
+
orderedAliases: ordered.map(item => item.alias)
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
306
329
|
private addOrUpdateConstituenta(
|
|
307
330
|
input: AddOrUpdateConstituentaInput,
|
|
308
331
|
sessionId?: string
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type ApplySchemaPatchInput,
|
|
3
3
|
type ApplySchemaPatchResult,
|
|
4
|
+
type RestoreOrderResult,
|
|
4
5
|
type SessionStateDetail,
|
|
5
6
|
type SessionStateResult
|
|
6
7
|
} from './agent-workflow';
|
|
@@ -12,7 +13,7 @@ import { type RecalculateModelResult, type SessionModelState, type SetModelValue
|
|
|
12
13
|
import { type SessionHandle, type SessionRevision, type SessionState } from './session';
|
|
13
14
|
|
|
14
15
|
/** Agent-visible contract version; bump on breaking API changes. */
|
|
15
|
-
export const CONTRACT_VERSION = '3.
|
|
16
|
+
export const CONTRACT_VERSION = '3.1.0';
|
|
16
17
|
|
|
17
18
|
/** Options for constructing an {@link RSToolAgent}. */
|
|
18
19
|
export interface RSToolAgentOptions {
|
|
@@ -85,4 +86,10 @@ export interface RSToolAgentContract {
|
|
|
85
86
|
|
|
86
87
|
/** Recompute derived model values for all constituents. */
|
|
87
88
|
recalculateModel(sessionId?: string): RecalculateModelResult;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Restore declaration order: formal topology, semantic clusters when ready,
|
|
92
|
+
* otherwise stable against type/kernel preferred ranks.
|
|
93
|
+
*/
|
|
94
|
+
restoreOrder(sessionId?: string): RestoreOrderResult;
|
|
88
95
|
}
|
|
@@ -33,7 +33,8 @@ export const STDIO_METHODS = [
|
|
|
33
33
|
'setModelValues',
|
|
34
34
|
'getModelState',
|
|
35
35
|
'evaluate',
|
|
36
|
-
'recalculateModel'
|
|
36
|
+
'recalculateModel',
|
|
37
|
+
'restoreOrder'
|
|
37
38
|
] as const;
|
|
38
39
|
|
|
39
40
|
function asObject(value: unknown): Record<string, unknown> {
|
|
@@ -171,6 +172,12 @@ export async function handleStdioRequest(tool: RSToolAgent, request: StdioReques
|
|
|
171
172
|
ok: true,
|
|
172
173
|
result: tool.recalculateModel(optionalSessionId(params))
|
|
173
174
|
};
|
|
175
|
+
case 'restoreOrder':
|
|
176
|
+
return {
|
|
177
|
+
id: request.id,
|
|
178
|
+
ok: true,
|
|
179
|
+
result: tool.restoreOrder(optionalSessionId(params))
|
|
180
|
+
};
|
|
174
181
|
default:
|
|
175
182
|
return {
|
|
176
183
|
id: request.id ?? null,
|