@rsconcept/rstool 0.10.2 → 1.0.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.
Files changed (112) hide show
  1. package/README.md +41 -31
  2. package/dist/agent-workflow-D-PSIb-m.d.ts +70 -0
  3. package/dist/analysis-LLnPhmGa.d.ts +23 -0
  4. package/dist/{common-DxLg3eXX.d.ts → common-DHJalS-Q.d.ts} +6 -1
  5. package/dist/constituenta-DnGR6bnM.d.ts +54 -0
  6. package/dist/diagnostic-D9yl_mEL.d.ts +19 -0
  7. package/dist/evaluation-Cns8BFm4.d.ts +31 -0
  8. package/dist/index.d.ts +11 -11
  9. package/dist/index.js +1 -1
  10. package/dist/mappers/model-adapter.d.ts +3 -3
  11. package/dist/mappers/schema-adapter.d.ts +4 -4
  12. package/dist/mappers/types.d.ts +6 -2
  13. package/dist/mappers/types.js +2 -0
  14. package/dist/mappers/types.js.map +1 -1
  15. package/dist/{model-value-SFAVj0dw.d.ts → model-value-BbonPzMz.d.ts} +14 -3
  16. package/dist/models/agent-workflow.d.ts +2 -0
  17. package/dist/models/agent-workflow.js +1 -0
  18. package/dist/models/analysis.d.ts +1 -1
  19. package/dist/models/common.d.ts +1 -1
  20. package/dist/models/constituenta.d.ts +2 -2
  21. package/dist/models/diagnostic.d.ts +1 -1
  22. package/dist/models/evaluation.d.ts +2 -2
  23. package/dist/models/index.d.ts +11 -11
  24. package/dist/models/index.js +2 -2
  25. package/dist/models/model-value.d.ts +2 -2
  26. package/dist/models/rstool-agent.d.ts +1 -1
  27. package/dist/models/rstool-agent.js +1 -1
  28. package/dist/models/session.d.ts +1 -1
  29. package/dist/models/tool-contract.d.ts +2 -2
  30. package/dist/models/tool-contract.js +2 -1
  31. package/dist/models/tool-contract.js.map +1 -1
  32. package/dist/rstool-agent-_8bplZnb.d.ts +71 -0
  33. package/dist/rstool-agent-kijHA9ML.js +476 -0
  34. package/dist/rstool-agent-kijHA9ML.js.map +1 -0
  35. package/dist/session/session-store.d.ts +18 -5
  36. package/dist/session/session-store.js +1 -64
  37. package/dist/{session-BPgsE80c.d.ts → session-ChexW8i7.d.ts} +11 -8
  38. package/dist/session-store-C3jyOSqI.js +142 -0
  39. package/dist/session-store-C3jyOSqI.js.map +1 -0
  40. package/dist/tool-contract-5_Q44DGE.d.ts +164 -0
  41. package/dist/wrapper/client.d.ts +23 -0
  42. package/dist/wrapper/client.js +17 -0
  43. package/dist/wrapper/client.js.map +1 -1
  44. package/dist/wrapper/stdio-wrapper.js +62 -52
  45. package/dist/wrapper/stdio-wrapper.js.map +1 -1
  46. package/docs/CONSTITUENTA.md +2 -2
  47. package/docs/DIAGNOSTICS.md +20 -18
  48. package/docs/MODEL-TESTING.md +3 -3
  49. package/docs/PORTAL-API.md +24 -18
  50. package/examples/README.md +1 -1
  51. package/examples/agent-client.ts +11 -41
  52. package/examples/build-chocolate-nim-rsform.ts +23 -18
  53. package/examples/chocolate-nim/build-rsform.ts +23 -18
  54. package/examples/chocolate-nim/build-rsmodel.ts +10 -12
  55. package/examples/chocolate-nim/rsform-session.json +290 -290
  56. package/examples/chocolate-nim/rsmodel-session.json +291 -291
  57. package/examples/expression-bank/bank-constituents.ts +304 -53
  58. package/examples/expression-bank/build-rsform.ts +19 -16
  59. package/examples/expression-bank/rsform-session.json +1551 -1551
  60. package/examples/kinship/build-rsform.ts +23 -18
  61. package/examples/kinship/build-rsmodel.ts +13 -15
  62. package/examples/kinship/rsform-session.json +219 -219
  63. package/examples/kinship/rsmodel-session.json +221 -221
  64. package/examples/kinship/session.ts +19 -21
  65. package/examples/movd/build-rsform.ts +23 -18
  66. package/examples/movd/build-rsmodel.ts +18 -20
  67. package/examples/movd/rsform-session.json +262 -262
  68. package/examples/movd/rsmodel-session.json +264 -264
  69. package/examples/sample/build-rsform.ts +19 -50
  70. package/examples/sample/build-rsmodel.ts +25 -44
  71. package/examples/sample/rsform-session.json +36 -33
  72. package/examples/sample/rsmodel-session.json +36 -33
  73. package/examples/template-apply/build-rsform.ts +27 -24
  74. package/examples/template-apply/rsform-session.json +48 -48
  75. package/package.json +3 -3
  76. package/skills/rstool-helper/EXAMPLES.md +44 -116
  77. package/skills/rstool-helper/GUIDE.md +40 -25
  78. package/skills/rstool-helper/REFERENCE.md +40 -177
  79. package/src/index.ts +24 -17
  80. package/src/mappers/portal-adapter.ts +43 -0
  81. package/src/mappers/types.ts +4 -0
  82. package/src/models/agent-workflow.ts +78 -0
  83. package/src/models/analysis.ts +7 -0
  84. package/src/models/common.ts +7 -0
  85. package/src/models/constituenta.ts +24 -6
  86. package/src/models/diagnostic.ts +4 -0
  87. package/src/models/evaluation.ts +11 -0
  88. package/src/models/import-detect.ts +39 -0
  89. package/src/models/import-export.ts +24 -0
  90. package/src/models/index.ts +22 -14
  91. package/src/models/model-value.ts +12 -0
  92. package/src/models/portal-json.ts +44 -0
  93. package/src/models/rstool-agent.test.ts +300 -147
  94. package/src/models/rstool-agent.ts +350 -93
  95. package/src/models/session.ts +8 -5
  96. package/src/models/tool-contract.ts +81 -42
  97. package/src/session/batch-apply.test.ts +28 -0
  98. package/src/session/batch-apply.ts +47 -0
  99. package/src/session/persistence.ts +56 -0
  100. package/src/session/session-store.ts +67 -4
  101. package/src/wrapper/client.ts +23 -0
  102. package/src/wrapper/stdio-wrapper.ts +59 -49
  103. package/dist/analysis-JiwOYDKx.d.ts +0 -16
  104. package/dist/constituenta-Dnd6iToB.d.ts +0 -36
  105. package/dist/diagnostic-BMYvciz8.d.ts +0 -15
  106. package/dist/evaluation-CCVYH0wA.d.ts +0 -21
  107. package/dist/index-uhkmwruf.d.ts +0 -46
  108. package/dist/rstool-agent-BZi5jO1y.js +0 -158
  109. package/dist/rstool-agent-BZi5jO1y.js.map +0 -1
  110. package/dist/rstool-agent-pRaPnZay.d.ts +0 -35
  111. package/dist/session/session-store.js.map +0 -1
  112. package/dist/tool-contract-n1ghUOrK.d.ts +0 -32
@@ -1,25 +1,25 @@
1
1
  #!/usr/bin/env node
2
- import { t as RSToolAgent } from "../rstool-agent-BZi5jO1y.js";
2
+ import { t as RSToolAgent } from "../rstool-agent-kijHA9ML.js";
3
3
  import readline from "node:readline";
4
4
  //#region src/wrapper/stdio-wrapper.ts
5
- const tool = new RSToolAgent();
5
+ const persistenceDir = process.env.RSTOOL_PERSISTENCE_DIR;
6
+ const tool = new RSToolAgent(persistenceDir ? { persistenceDir } : {});
6
7
  const METHODS = [
8
+ "ensureSession",
7
9
  "createSession",
8
- "addOrUpdateConstituenta",
9
- "analyzeExpression",
10
- "getFormState",
10
+ "getCurrentSession",
11
+ "setCurrentSession",
12
+ "applySchemaPatch",
13
+ "getSessionState",
11
14
  "listDiagnostics",
15
+ "analyzeExpression",
12
16
  "commitStep",
13
17
  "exportSession",
14
- "exportPortalSchema",
15
- "exportPortalModel",
16
- "importSession",
17
- "setConstituentaValue",
18
- "setConstituentaValues",
19
- "clearConstituentaValues",
18
+ "exportPortal",
19
+ "importData",
20
+ "setModelValues",
20
21
  "getModelState",
21
- "evaluateExpression",
22
- "evaluateConstituenta",
22
+ "evaluate",
23
23
  "recalculateModel"
24
24
  ];
25
25
  function writeResponse(response) {
@@ -37,6 +37,14 @@ function requiredString(input, key) {
37
37
  if (typeof value !== "string" || value.length === 0) throw new Error(`Missing or invalid "${key}"`);
38
38
  return value;
39
39
  }
40
+ function optionalSessionId(input) {
41
+ const value = input.sessionId;
42
+ return typeof value === "string" && value.length > 0 ? value : void 0;
43
+ }
44
+ function omitSessionId(input) {
45
+ const { sessionId: _sessionId, ...rest } = input;
46
+ return rest;
47
+ }
40
48
  async function handleRequest(request) {
41
49
  try {
42
50
  const params = asObject(request.params);
@@ -44,97 +52,99 @@ async function handleRequest(request) {
44
52
  case "ping": return {
45
53
  id: request.id,
46
54
  ok: true,
47
- result: { pong: true }
55
+ result: {
56
+ pong: true,
57
+ contractVersion: tool.contractVersion
58
+ }
48
59
  };
49
60
  case "methods": return {
50
61
  id: request.id,
51
62
  ok: true,
52
63
  result: METHODS
53
64
  };
54
- case "createSession": return {
65
+ case "ensureSession": return {
55
66
  id: request.id,
56
67
  ok: true,
57
- result: tool.createSession(params.initial)
68
+ result: tool.ensureSession(params.initial)
58
69
  };
59
- case "addOrUpdateConstituenta": return {
60
- id: request.id,
61
- ok: true,
62
- result: tool.addOrUpdateConstituenta(requiredString(params, "sessionId"), params.input)
63
- };
64
- case "analyzeExpression": return {
70
+ case "createSession": return {
65
71
  id: request.id,
66
72
  ok: true,
67
- result: tool.analyzeExpression(requiredString(params, "sessionId"), params.input)
73
+ result: tool.createSession(params.initial)
68
74
  };
69
- case "getFormState": return {
75
+ case "getCurrentSession": return {
70
76
  id: request.id,
71
77
  ok: true,
72
- result: tool.getFormState(requiredString(params, "sessionId"))
78
+ result: tool.getCurrentSession()
73
79
  };
74
- case "listDiagnostics": return {
80
+ case "setCurrentSession": return {
75
81
  id: request.id,
76
82
  ok: true,
77
- result: tool.listDiagnostics(requiredString(params, "sessionId"), params.filters)
83
+ result: tool.setCurrentSession(requiredString(params, "sessionId"))
78
84
  };
79
- case "commitStep": return {
85
+ case "applySchemaPatch": return {
80
86
  id: request.id,
81
87
  ok: true,
82
- result: tool.commitStep(requiredString(params, "sessionId"), params.message)
88
+ result: tool.applySchemaPatch(omitSessionId(params), optionalSessionId(params))
83
89
  };
84
- case "exportSession": return {
90
+ case "getSessionState": return {
85
91
  id: request.id,
86
92
  ok: true,
87
- result: tool.exportSession(requiredString(params, "sessionId"))
93
+ result: tool.getSessionState(params.detail ?? "summary", optionalSessionId(params))
88
94
  };
89
- case "exportPortalSchema": return {
95
+ case "listDiagnostics": {
96
+ const constituentId = params.constituentId;
97
+ const filters = typeof constituentId === "number" ? { constituentId } : params.filters;
98
+ return {
99
+ id: request.id,
100
+ ok: true,
101
+ result: tool.listDiagnostics(filters, optionalSessionId(params))
102
+ };
103
+ }
104
+ case "analyzeExpression": return {
90
105
  id: request.id,
91
106
  ok: true,
92
- result: tool.exportPortalSchema(requiredString(params, "sessionId"))
107
+ result: tool.analyzeExpression(omitSessionId(params), optionalSessionId(params))
93
108
  };
94
- case "exportPortalModel": return {
109
+ case "commitStep": return {
95
110
  id: request.id,
96
111
  ok: true,
97
- result: tool.exportPortalModel(requiredString(params, "sessionId"))
112
+ result: tool.commitStep(params.message, optionalSessionId(params))
98
113
  };
99
- case "importSession": return {
114
+ case "exportSession": return {
100
115
  id: request.id,
101
116
  ok: true,
102
- result: tool.importSession(requiredString(params, "payload"))
117
+ result: tool.exportSession(optionalSessionId(params))
103
118
  };
104
- case "setConstituentaValue": return {
119
+ case "exportPortal": return {
105
120
  id: request.id,
106
121
  ok: true,
107
- result: await tool.setConstituentaValue(requiredString(params, "sessionId"), params.input)
122
+ result: tool.exportPortal(omitSessionId(params), optionalSessionId(params))
108
123
  };
109
- case "setConstituentaValues": return {
124
+ case "importData": return {
110
125
  id: request.id,
111
126
  ok: true,
112
- result: await tool.setConstituentaValues(requiredString(params, "sessionId"), params.input)
127
+ result: tool.importData(params.payload, params.kind)
113
128
  };
114
- case "clearConstituentaValues": return {
129
+ case "setModelValues": return {
115
130
  id: request.id,
116
131
  ok: true,
117
- result: await tool.clearConstituentaValues(requiredString(params, "sessionId"), params.input)
132
+ result: await tool.setModelValues(omitSessionId(params), optionalSessionId(params))
118
133
  };
119
134
  case "getModelState": return {
120
135
  id: request.id,
121
136
  ok: true,
122
- result: tool.getModelState(requiredString(params, "sessionId"))
123
- };
124
- case "evaluateExpression": return {
125
- id: request.id,
126
- ok: true,
127
- result: tool.evaluateExpression(requiredString(params, "sessionId"), params.input)
137
+ result: tool.getModelState(optionalSessionId(params))
128
138
  };
129
- case "evaluateConstituenta": return {
139
+ case "evaluate": return {
130
140
  id: request.id,
131
141
  ok: true,
132
- result: tool.evaluateConstituenta(requiredString(params, "sessionId"), params.input)
142
+ result: tool.evaluate(omitSessionId(params), optionalSessionId(params))
133
143
  };
134
144
  case "recalculateModel": return {
135
145
  id: request.id,
136
146
  ok: true,
137
- result: tool.recalculateModel(requiredString(params, "sessionId"))
147
+ result: tool.recalculateModel(optionalSessionId(params))
138
148
  };
139
149
  default: return {
140
150
  id: request.id ?? null,
@@ -1 +1 @@
1
- {"version":3,"file":"stdio-wrapper.js","names":[],"sources":["../../src/wrapper/stdio-wrapper.ts"],"sourcesContent":["#!/usr/bin/env node\nimport readline from 'node:readline';\n\nimport { RSToolAgent } from '../models/rstool-agent';\n\ninterface StdioRequest {\n id: string | number;\n method: string;\n params?: unknown;\n}\n\ninterface StdioResponse {\n id: string | number | null;\n ok: boolean;\n result?: unknown;\n error?: {\n code: string;\n message: string;\n details?: unknown;\n };\n}\n\nconst tool = new RSToolAgent();\n\nconst METHODS = [\n 'createSession',\n 'addOrUpdateConstituenta',\n 'analyzeExpression',\n 'getFormState',\n 'listDiagnostics',\n 'commitStep',\n 'exportSession',\n 'exportPortalSchema',\n 'exportPortalModel',\n 'importSession',\n 'setConstituentaValue',\n 'setConstituentaValues',\n 'clearConstituentaValues',\n 'getModelState',\n 'evaluateExpression',\n 'evaluateConstituenta',\n 'recalculateModel'\n] as const;\n\nfunction writeResponse(response: StdioResponse): void {\n if (!process.stdout.writable || process.stdout.destroyed || process.stdout.writableEnded) {\n return;\n }\n try {\n process.stdout.write(`${JSON.stringify(response)}\\n`);\n } catch {\n // The client might have already closed stdout (EPIPE). Safe to ignore.\n }\n}\n\nfunction asObject(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return {};\n }\n return value as Record<string, unknown>;\n}\n\nfunction requiredString(input: Record<string, unknown>, key: string): string {\n const value = input[key];\n if (typeof value !== 'string' || value.length === 0) {\n throw new Error(`Missing or invalid \"${key}\"`);\n }\n return value;\n}\n\nasync function handleRequest(request: StdioRequest): Promise<StdioResponse> {\n try {\n const params = asObject(request.params);\n switch (request.method) {\n case 'ping':\n return { id: request.id, ok: true, result: { pong: true } };\n case 'methods':\n return { id: request.id, ok: true, result: METHODS };\n case 'createSession':\n return {\n id: request.id,\n ok: true,\n result: tool.createSession(params.initial as never)\n };\n case 'addOrUpdateConstituenta':\n return {\n id: request.id,\n ok: true,\n result: tool.addOrUpdateConstituenta(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'analyzeExpression':\n return {\n id: request.id,\n ok: true,\n result: tool.analyzeExpression(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'getFormState':\n return {\n id: request.id,\n ok: true,\n result: tool.getFormState(requiredString(params, 'sessionId'))\n };\n case 'listDiagnostics':\n return {\n id: request.id,\n ok: true,\n result: tool.listDiagnostics(requiredString(params, 'sessionId'), params.filters as never)\n };\n case 'commitStep':\n return {\n id: request.id,\n ok: true,\n result: tool.commitStep(requiredString(params, 'sessionId'), params.message as string | undefined)\n };\n case 'exportSession':\n return {\n id: request.id,\n ok: true,\n result: tool.exportSession(requiredString(params, 'sessionId'))\n };\n case 'exportPortalSchema':\n return {\n id: request.id,\n ok: true,\n result: tool.exportPortalSchema(requiredString(params, 'sessionId'))\n };\n case 'exportPortalModel':\n return {\n id: request.id,\n ok: true,\n result: tool.exportPortalModel(requiredString(params, 'sessionId'))\n };\n case 'importSession':\n return {\n id: request.id,\n ok: true,\n result: tool.importSession(requiredString(params, 'payload'))\n };\n case 'setConstituentaValue':\n return {\n id: request.id,\n ok: true,\n result: await tool.setConstituentaValue(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'setConstituentaValues':\n return {\n id: request.id,\n ok: true,\n result: await tool.setConstituentaValues(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'clearConstituentaValues':\n return {\n id: request.id,\n ok: true,\n result: await tool.clearConstituentaValues(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'getModelState':\n return {\n id: request.id,\n ok: true,\n result: tool.getModelState(requiredString(params, 'sessionId'))\n };\n case 'evaluateExpression':\n return {\n id: request.id,\n ok: true,\n result: tool.evaluateExpression(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'evaluateConstituenta':\n return {\n id: request.id,\n ok: true,\n result: tool.evaluateConstituenta(requiredString(params, 'sessionId'), params.input as never)\n };\n case 'recalculateModel':\n return {\n id: request.id,\n ok: true,\n result: tool.recalculateModel(requiredString(params, 'sessionId'))\n };\n default:\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'METHOD_NOT_FOUND',\n message: `Unknown method: ${request.method}`\n }\n };\n }\n } catch (error) {\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'INTERNAL_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error\n }\n };\n }\n}\n\nconst input = readline.createInterface({\n input: process.stdin,\n crlfDelay: Infinity\n});\n\nwriteResponse({\n id: null,\n ok: true,\n result: {\n ready: true,\n wrapper: 'rstool-stdio',\n contractVersion: tool.contractVersion\n }\n});\n\ninput.on('line', line => {\n if (!line.trim()) {\n return;\n }\n try {\n const request = JSON.parse(line) as StdioRequest;\n if (!('id' in request) || !('method' in request)) {\n throw new Error('Request must include \"id\" and \"method\"');\n }\n void handleRequest(request).then(writeResponse);\n } catch (error) {\n writeResponse({\n id: null,\n ok: false,\n error: {\n code: 'BAD_REQUEST',\n message: error instanceof Error ? error.message : 'Invalid JSON'\n }\n });\n }\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"stdio-wrapper.js","names":[],"sources":["../../src/wrapper/stdio-wrapper.ts"],"sourcesContent":["#!/usr/bin/env node\nimport readline from 'node:readline';\n\nimport { RSToolAgent } from '../models/rstool-agent';\n\ninterface StdioRequest {\n id: string | number;\n method: string;\n params?: unknown;\n}\n\ninterface StdioResponse {\n id: string | number | null;\n ok: boolean;\n result?: unknown;\n error?: {\n code: string;\n message: string;\n details?: unknown;\n };\n}\n\nconst persistenceDir = process.env.RSTOOL_PERSISTENCE_DIR;\nconst tool = new RSToolAgent(persistenceDir ? { persistenceDir } : {});\n\nconst METHODS = [\n 'ensureSession',\n 'createSession',\n 'getCurrentSession',\n 'setCurrentSession',\n 'applySchemaPatch',\n 'getSessionState',\n 'listDiagnostics',\n 'analyzeExpression',\n 'commitStep',\n 'exportSession',\n 'exportPortal',\n 'importData',\n 'setModelValues',\n 'getModelState',\n 'evaluate',\n 'recalculateModel'\n] as const;\n\nfunction writeResponse(response: StdioResponse): void {\n if (!process.stdout.writable || process.stdout.destroyed || process.stdout.writableEnded) {\n return;\n }\n try {\n process.stdout.write(`${JSON.stringify(response)}\\n`);\n } catch {\n // The client might have already closed stdout (EPIPE). Safe to ignore.\n }\n}\n\nfunction asObject(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n return {};\n }\n return value as Record<string, unknown>;\n}\n\nfunction requiredString(input: Record<string, unknown>, key: string): string {\n const value = input[key];\n if (typeof value !== 'string' || value.length === 0) {\n throw new Error(`Missing or invalid \"${key}\"`);\n }\n return value;\n}\n\nfunction optionalSessionId(input: Record<string, unknown>): string | undefined {\n const value = input.sessionId;\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\nfunction omitSessionId(input: Record<string, unknown>): Record<string, unknown> {\n const { sessionId: _sessionId, ...rest } = input;\n return rest;\n}\n\nasync function handleRequest(request: StdioRequest): Promise<StdioResponse> {\n try {\n const params = asObject(request.params);\n switch (request.method) {\n case 'ping':\n return { id: request.id, ok: true, result: { pong: true, contractVersion: tool.contractVersion } };\n case 'methods':\n return { id: request.id, ok: true, result: METHODS };\n case 'ensureSession':\n return {\n id: request.id,\n ok: true,\n result: tool.ensureSession(params.initial as never)\n };\n case 'createSession':\n return {\n id: request.id,\n ok: true,\n result: tool.createSession(params.initial as never)\n };\n case 'getCurrentSession':\n return {\n id: request.id,\n ok: true,\n result: tool.getCurrentSession()\n };\n case 'setCurrentSession':\n return {\n id: request.id,\n ok: true,\n result: tool.setCurrentSession(requiredString(params, 'sessionId'))\n };\n case 'applySchemaPatch':\n return {\n id: request.id,\n ok: true,\n result: tool.applySchemaPatch(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'getSessionState':\n return {\n id: request.id,\n ok: true,\n result: tool.getSessionState(\n (params.detail as 'summary' | 'full' | undefined) ?? 'summary',\n optionalSessionId(params)\n )\n };\n case 'listDiagnostics': {\n const constituentId = params.constituentId;\n const filters = typeof constituentId === 'number' ? { constituentId } : (params.filters as never);\n return {\n id: request.id,\n ok: true,\n result: tool.listDiagnostics(filters, optionalSessionId(params))\n };\n }\n case 'analyzeExpression':\n return {\n id: request.id,\n ok: true,\n result: tool.analyzeExpression(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'commitStep':\n return {\n id: request.id,\n ok: true,\n result: tool.commitStep(params.message as string | undefined, optionalSessionId(params))\n };\n case 'exportSession':\n return {\n id: request.id,\n ok: true,\n result: tool.exportSession(optionalSessionId(params))\n };\n case 'exportPortal':\n return {\n id: request.id,\n ok: true,\n result: tool.exportPortal(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'importData':\n return {\n id: request.id,\n ok: true,\n result: tool.importData(params.payload as string | object, params.kind as never)\n };\n case 'setModelValues':\n return {\n id: request.id,\n ok: true,\n result: await tool.setModelValues(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'getModelState':\n return {\n id: request.id,\n ok: true,\n result: tool.getModelState(optionalSessionId(params))\n };\n case 'evaluate':\n return {\n id: request.id,\n ok: true,\n result: tool.evaluate(omitSessionId(params) as never, optionalSessionId(params))\n };\n case 'recalculateModel':\n return {\n id: request.id,\n ok: true,\n result: tool.recalculateModel(optionalSessionId(params))\n };\n default:\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'METHOD_NOT_FOUND',\n message: `Unknown method: ${request.method}`\n }\n };\n }\n } catch (error) {\n return {\n id: request.id ?? null,\n ok: false,\n error: {\n code: 'INTERNAL_ERROR',\n message: error instanceof Error ? error.message : 'Unknown error',\n details: error\n }\n };\n }\n}\n\nconst input = readline.createInterface({\n input: process.stdin,\n crlfDelay: Infinity\n});\n\nwriteResponse({\n id: null,\n ok: true,\n result: {\n ready: true,\n wrapper: 'rstool-stdio',\n contractVersion: tool.contractVersion\n }\n});\n\ninput.on('line', line => {\n if (!line.trim()) {\n return;\n }\n try {\n const request = JSON.parse(line) as StdioRequest;\n if (!('id' in request) || !('method' in request)) {\n throw new Error('Request must include \"id\" and \"method\"');\n }\n void handleRequest(request).then(writeResponse);\n } catch (error) {\n writeResponse({\n id: null,\n ok: false,\n error: {\n code: 'BAD_REQUEST',\n message: error instanceof Error ? error.message : 'Invalid JSON'\n }\n });\n }\n});\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  # Конституенты
2
2
 
3
- Читай перед `addOrUpdateConstituenta`.
3
+ Читай перед `applySchemaPatch`.
4
4
 
5
5
  ## Поля
6
6
 
@@ -28,7 +28,7 @@
28
28
  - `axiom` / `A#` — аксиома; нужна типизация `Logic`.
29
29
  - `statement` / `T#` — высказывание; нужна типизация `Logic`.
30
30
 
31
- В модели `basic`, `constant`, `structure` можно интерпретировать через `setConstituentaValue`. `term`, `axiom`, `statement` вычисляются и напрямую не задаются.
31
+ В модели `basic`, `constant`, `structure` можно интерпретировать через `setModelValues`. `term`, `function`, `predicate`, `axiom`, `statement` вычисляются и напрямую не задаются.
32
32
 
33
33
  ## Различие родовой структуры и терма
34
34
 
@@ -1,6 +1,6 @@
1
1
  # Диагностика
2
2
 
3
- Читай, когда `analyzeExpression`, `addOrUpdateConstituenta`, `listDiagnostics` или `evaluate*`
3
+ Читай, когда `analyzeExpression`, `applySchemaPatch`, `listDiagnostics` или `evaluate`
4
4
  вернули диагностику. Источник истины по кодам — `@rsconcept/domain/src/rslang/error.ts`.
5
5
 
6
6
  ## Где лежит диагностика
@@ -8,15 +8,16 @@
8
8
  У rstool два представления одной и той же ошибки.
9
9
 
10
10
  - **Плоское** `RSToolErrorDescription` — в `AnalysisResult.diagnostics` (из `analyzeExpression`
11
- и `addOrUpdateConstituenta(...).analysis`) и в `EvaluationResult.diagnostics`:
11
+ и анализа конституент после `applySchemaPatch`) и в `EvaluationResult.diagnostics`:
12
12
  - `code` — числовой `RSErrorCode`.
13
13
  - `from`, `to` — полуинтервал `[from, to)` в `definitionFormal` (или в выражении вычисления).
14
14
  - `params?` — позиционный массив строк-аргументов сообщения (см. таблицы ниже).
15
15
  - **Обёрнутое** `DiagnosticRecord` — только из `listDiagnostics`:
16
16
  - `sessionId`, `expression` — исходное выражение.
17
17
  - `error` — то же `RSToolErrorDescription` (`code`/`from`/`to`/`params`) **вложено**, читай `record.error.code`.
18
- - `constituentId?` — id конституенты. У диагностик от `addOrUpdateConstituenta` он есть;
19
- у черновиков `analyzeExpression` он `undefined`. Фильтруй `listDiagnostics(sessionId, { constituentId })`.
18
+ - `constituentId?` — id конституенты. У диагностик сохранённых конституент он есть;
19
+ у черновиков `analyzeExpression` он `undefined`. Фильтруй `listDiagnostics({ constituentId })`
20
+ или `listDiagnostics({ constituentId }, sessionId)`.
20
21
 
21
22
  ## Класс и префикс кода
22
23
 
@@ -36,19 +37,20 @@
36
37
 
37
38
  ## Parser
38
39
 
39
- | Код | Имя | `params` | Исправление |
40
- | :------- | :----------------------- | :------------------------ | :------------------------------------------------------------------------------- |
41
- | `0x8400` | `unknownSyntax` | — | Неопределённая синтаксическая ошибка: проверь операторы, скобки, идентификаторы. |
42
- | `0x8409` | `bracketMismatch` | `[expected, actual]` | Закрой ожидаемой скобкой `expected` вместо `actual`. |
43
- | `0x840A` | `doubleParenthesis` | | Убери лишнюю внешнюю пару `(( ))`. |
44
- | `0x840B` | `missingOpenBracket` | `[bracket]` | Непарная закрывающая `bracket`: убери её или добавь открывающую. |
45
- | `0x840C` | `missingCloseBracket` | `[bracket]` | Непарная открывающая `bracket`: убери её или добавь закрывающую. |
46
- | `0x8415` | `expectedLocal` | | Ожидалось имя локальной переменной. |
47
- | `0x8416` | `expectedType` | `[expectedClass, actual]` | Несоответствие класса выражения ожидаемому. |
48
- | `0x8417` | `invalidFilterSyntax` | — | Синтаксис `Fi`: `Fi1[D1](S1)`, `Fi1,2[D1,D2](S1)` или `Fi1,2[D3](S1)`. |
49
- | `0x8418` | `expectedFunctionBody` | — | Нужно тело функции после `[параметры]`. |
50
- | `0x8419` | `expectedExpressionBody` | — | Нужно теоретико-множественное тело функции (ТФ). |
51
- | `0x841A` | `expectedLogicBody` | — | Нужно логическое тело функции. |
40
+ | Код | Имя | `params` | Исправление |
41
+ | :------- | :----------------------- | :------------------------ | :------------------------------------------------------------------------------------ |
42
+ | `0x8400` | `unknownSyntax` | — | Неопределённая синтаксическая ошибка: проверь операторы, скобки, идентификаторы. |
43
+ | `0x8401` | `forbiddenCharacter` | `[character]` | Символ не входит в язык родов структур (напр. `^` для степени). Удали или замени его. |
44
+ | `0x8409` | `bracketMismatch` | `[expected, actual]` | Закрой ожидаемой скобкой `expected` вместо `actual`. |
45
+ | `0x840A` | `doubleParenthesis` | | Убери лишнюю внешнюю пару `(( ))`. |
46
+ | `0x840B` | `missingOpenBracket` | `[bracket]` | Непарная закрывающая `bracket`: убери её или добавь открывающую. |
47
+ | `0x840C` | `missingCloseBracket` | `[bracket]` | Непарная открывающая `bracket`: убери её или добавь закрывающую. |
48
+ | `0x8415` | `expectedLocal` | | Ожидалось имя локальной переменной. |
49
+ | `0x8416` | `expectedType` | `[expectedClass, actual]` | Несоответствие класса выражения ожидаемому. |
50
+ | `0x8417` | `invalidFilterSyntax` | — | Синтаксис `Fi`: `Fi1[D1](S1)`, `Fi1,2[D1,D2](S1)` или `Fi1,2[D3](S1)`. |
51
+ | `0x8418` | `expectedFunctionBody` | — | Нужно тело функции после `[параметры]`. |
52
+ | `0x8419` | `expectedExpressionBody` | — | Нужно теоретико-множественное тело функции (ТФ). |
53
+ | `0x841A` | `expectedLogicBody` | — | Нужно логическое тело функции. |
52
54
 
53
55
  ## Предупреждения
54
56
 
@@ -127,7 +129,7 @@
127
129
  | `0x8100` | `calcUnknownError` | — | Непредвиденная ошибка вычисления. |
128
130
  | `0x8101` | `setOverflow` | `[limit]` | Превышен предел числа элементов `limit`: упрости выражение или данные. |
129
131
  | `0x8102` | `booleanBaseLimit` | `[limit]` | Превышен предел базы степенного множества `limit`. |
130
- | `0x8103` | `calcGlobalMissing` | `[name]` | Нет значения для `name`: задай `setConstituentaValue(s)`. |
132
+ | `0x8103` | `calcGlobalMissing` | `[name]` | Нет значения для `name`: задай через `setModelValues`. |
131
133
  | `0x8104` | `iterationsLimit` | `[limit]` | Превышен предел итераций `limit`. |
132
134
  | `0x8105` | `calcInvalidDebool` | — | `debool` получил не синглетон. |
133
135
  | `0x8106` | `iterateInfinity` | — | Итерация по бесконечному множеству. |
@@ -15,13 +15,13 @@
15
15
 
16
16
  `basic`, `constant`, `structure` можно интерпретировать напрямую. `term`, `function`, `predicate`, `axiom`, `statement` должны вычисляться из формулы, поэтому их напрямую не задавай.
17
17
 
18
- Пример формы данных:
18
+ Пример формы данных (`setModelValues` — асинхронный, нужен `await`):
19
19
 
20
20
  ```ts
21
21
  import { TUPLE_ID } from '@rsconcept/domain';
22
22
 
23
- tool.setConstituentaValues(sessionId, {
24
- items: [
23
+ await tool.setModelValues({
24
+ set: [
25
25
  { target: 1, value: { 0: 'ann', 1: 'bob', 2: 'cat' } },
26
26
  {
27
27
  target: 2,
@@ -224,19 +224,24 @@ curl.exe -s "https://api.portal.acconcept.ru/api/rsforms/856/details"
224
224
  ## Как перенести КС в rstool
225
225
 
226
226
  1. Получи `GET /api/rsforms/:id/details`.
227
- 2. Создай `createSession({ title, alias, comment: description })`.
228
- 3. Иди по `items[]` в порядке ответа API.
229
- 4. Для каждого элемента вызови `addOrUpdateConstituenta(sessionId, { draft })`.
230
- 5. Проверь `listDiagnostics(sessionId)`.
231
- 6. Работай локально: анализ, правки, вычисления, маленькая КМ.
232
- 7. Для сохранения рабочей сессии используй `exportSession`.
233
- 8. Для загрузки схемы обратно в Portal используй `exportPortalSchema`.
227
+ 2. Вызови `importData(JSON.stringify(payload))` auto определит `portal-details`; для Load from JSON — `importData(payload, 'portal-schema')`.
228
+ 3. Проверь `listDiagnostics()` (после `importData` сессия уже текущая).
229
+ 4. Работай локально: анализ, правки, вычисления, маленькая КМ.
230
+ 5. Для сохранения рабочей сессии используй `exportSession`.
231
+ 6. Для загрузки схемы обратно в Portal используй `exportPortal({ kind: 'schema' })`.
234
232
 
235
- Portal JSON из `/details` **не является** форматом `exportSession` и не передаётся
236
- в `importSession` напрямую. Его нужно перенести через `addOrUpdateConstituenta`
237
- или через отдельный адаптер, если он появится в контракте.
233
+ Альтернатива: `createSession` + `applySchemaPatch` с массивом `items`.
238
234
 
239
- Минимальный маппинг:
235
+ Portal JSON из `/details` **не является** форматом `exportSession`; используй `importData`, не передавай его как session export.
236
+
237
+ Минимальный импорт:
238
+
239
+ ```ts
240
+ const session = tool.importData(JSON.stringify(portal));
241
+ tool.listDiagnostics();
242
+ ```
243
+
244
+ Пакетный маппинг через `applySchemaPatch`:
240
245
 
241
246
  ```ts
242
247
  const session = tool.createSession({
@@ -245,9 +250,9 @@ const session = tool.createSession({
245
250
  comment: portal.description
246
251
  });
247
252
 
248
- for (const item of portal.items) {
249
- tool.addOrUpdateConstituenta(session.sessionId, {
250
- draft: {
253
+ tool.applySchemaPatch(
254
+ {
255
+ items: portal.items.map(item => ({
251
256
  id: item.id,
252
257
  alias: item.alias,
253
258
  cstType: item.cst_type,
@@ -255,9 +260,10 @@ for (const item of portal.items) {
255
260
  term: item.term_raw ?? '',
256
261
  definitionText: item.definition_raw ?? '',
257
262
  convention: item.convention ?? ''
258
- }
259
- });
260
- }
263
+ }))
264
+ },
265
+ session.sessionId
266
+ );
261
267
  ```
262
268
 
263
269
  ## Практика для агентов
@@ -294,5 +300,5 @@ path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding='utf
294
300
  - Не парси HTML SPA.
295
301
  - Не запрашивай UI напрямую, используй преобразованные API запросы.
296
302
  - Не предлагай авторизацию через session cookie или `sessionid` в curl.
297
- - Не передавай `/details` JSON в `importSession`.
303
+ - Не передавай `/details` JSON в `importData` с `kind: 'session'`.
298
304
  - Не запрашивай `/details`, если нужны только метаданные.
@@ -30,7 +30,7 @@ npx tsx node_modules/@rsconcept/rstool/examples/agent-client.ts
30
30
  | `build-rsform.ts` | Сборка RSForm → `rsform-session.json` |
31
31
  | `build-rsmodel.ts` | Демо-модель и проверки → `rsmodel-session.json` |
32
32
 
33
- Готовые `*-session.json` — снимки `exportSession` для `importSession` и тестов. Пересобрать: соответствующий `build-*.ts` перезапишет файл рядом с собой.
33
+ Готовые `*-session.json` — снимки `exportSession` для `importData` и тестов. Пересобрать: соответствующий `build-*.ts` перезапишет файл рядом с собой.
34
34
 
35
35
  ## Темы и npm-скрипты
36
36
 
@@ -1,4 +1,4 @@
1
- import { CstType, RSToolWrapperClient, type AddOrUpdateConstituentaInput, type AnalyzeExpressionInput } from '../src';
1
+ import { CstType, RSToolWrapperClient, type AnalyzeExpressionInput } from '../src';
2
2
 
3
3
  interface CreateSessionResult {
4
4
  sessionId: string;
@@ -13,41 +13,16 @@ async function runExample() {
13
13
  const session = await client.call<CreateSessionResult>('createSession');
14
14
  console.log('Session created:', session);
15
15
 
16
- const baseInput: AddOrUpdateConstituentaInput = {
17
- draft: {
18
- id: 1,
19
- alias: 'X1',
20
- cstType: CstType.BASE,
21
- definitionFormal: ''
22
- }
23
- };
24
- await client.call('addOrUpdateConstituenta', {
25
- sessionId: session.sessionId,
26
- input: baseInput
27
- });
28
-
29
- const upsertInput: AddOrUpdateConstituentaInput = {
30
- draft: {
31
- id: 2,
32
- alias: 'D1',
33
- cstType: CstType.TERM,
34
- definitionFormal: '1+2'
35
- }
36
- };
37
- const upsert = await client.call('addOrUpdateConstituenta', {
38
- sessionId: session.sessionId,
39
- input: upsertInput
16
+ await client.call('applySchemaPatch', {
17
+ items: [{ alias: 'X1' }, { alias: 'D1', definitionFormal: '1+2' }]
40
18
  });
41
- console.log('Upsert result:', upsert);
42
19
 
43
- await client.call('setConstituentaValue', {
44
- sessionId: session.sessionId,
45
- input: { target: 1, value: { 0: 'zero', 1: 'one' } }
20
+ await client.call('setModelValues', {
21
+ set: [{ target: 1, value: { 0: 'zero', 1: 'one' } }]
46
22
  });
47
23
 
48
- const evalResult = await client.call('evaluateConstituenta', {
49
- sessionId: session.sessionId,
50
- input: { constituentId: 2 }
24
+ const evalResult = await client.call('evaluate', {
25
+ constituentId: 2
51
26
  });
52
27
  console.log('Evaluation result:', evalResult);
53
28
 
@@ -55,16 +30,11 @@ async function runExample() {
55
30
  expression: '(',
56
31
  cstType: CstType.TERM
57
32
  };
58
- const analysis = await client.call('analyzeExpression', {
59
- sessionId: session.sessionId,
60
- input: analyzeInput
61
- });
62
- console.log('Analysis result:', analysis);
33
+ const analysis = await client.call<{ diagnostics: unknown[] }>('analyzeExpression', analyzeInput);
34
+ console.log('Scratch analysis diagnostics:', analysis.diagnostics.length);
63
35
 
64
- const diagnostics = await client.call('listDiagnostics', {
65
- sessionId: session.sessionId
66
- });
67
- console.log('Diagnostics count:', Array.isArray(diagnostics) ? diagnostics.length : diagnostics);
36
+ const sessionDiagnostics = await client.call<unknown[]>('listDiagnostics', {});
37
+ console.log('Session diagnostics count:', sessionDiagnostics.length);
68
38
  } finally {
69
39
  await client.close();
70
40
  }
@@ -1,7 +1,9 @@
1
1
  import { writeFile } from 'node:fs/promises';
2
2
  import { resolve } from 'node:path';
3
3
 
4
- import { CstType, RSToolWrapperClient, type AddOrUpdateConstituentaInput } from '../src';
4
+ import { CstType, RSToolWrapperClient, type AgentConstituentaPatch } from '../src';
5
+
6
+ type DraftBatch = { draft: AgentConstituentaPatch };
5
7
 
6
8
  import { DEFAULT_RSFORM_SESSION_PATH } from './chocolate-nim/constants';
7
9
 
@@ -18,7 +20,7 @@ async function run() {
18
20
  await client.waitUntilReady();
19
21
  const session = await client.call<{ sessionId: string; contractVersion: string }>('createSession');
20
22
 
21
- const drafts: AddOrUpdateConstituentaInput[] = [
23
+ const drafts: DraftBatch[] = [
22
24
  {
23
25
  draft: {
24
26
  id: 1,
@@ -271,22 +273,25 @@ async function run() {
271
273
  }
272
274
  ];
273
275
 
274
- for (const input of drafts) {
275
- const result = await client.call<{
276
- state: { alias: string; analysis: { success: boolean } };
277
- diagnostics: unknown[];
278
- }>('addOrUpdateConstituenta', {
279
- sessionId: session.sessionId,
280
- input
281
- });
282
- const ok = result.state.analysis.success;
283
- const diagCount = result.diagnostics?.length ?? 0;
284
- console.log(`${input.draft.alias}: ${ok ? 'OK' : 'FAIL'} (${diagCount} diagnostics)`);
285
- if (!ok) {
286
- const diags = await client.call('listDiagnostics', { sessionId: session.sessionId });
287
- console.log(JSON.stringify(diags, null, 2));
288
- throw new Error(`${input.draft.alias}: analysis failed (${diagCount} diagnostics)`);
289
- }
276
+ const patch = await client.call<{
277
+ success: boolean;
278
+ diagnostics: unknown[];
279
+ failed: Array<{ draft: { alias: string }; diagnostics: unknown[] }>;
280
+ summary: { items: Array<{ alias: string; analysisSuccess: boolean }> };
281
+ }>('applySchemaPatch', {
282
+ sessionId: session.sessionId,
283
+ mode: 'atomic',
284
+ items: drafts.map(entry => entry.draft)
285
+ });
286
+
287
+ for (const item of patch.summary.items) {
288
+ console.log(`${item.alias}: ${item.analysisSuccess ? 'OK' : 'FAIL'}`);
289
+ }
290
+ if (!patch.success) {
291
+ const diags = await client.call('listDiagnostics', { sessionId: session.sessionId });
292
+ console.log(JSON.stringify(diags, null, 2));
293
+ const failedAlias = patch.failed[0]?.draft.alias ?? 'unknown';
294
+ throw new Error(`${failedAlias}: analysis failed`);
290
295
  }
291
296
 
292
297
  await client.call('commitStep', {
@@ -1,7 +1,9 @@
1
1
  import { writeFile } from 'node:fs/promises';
2
2
  import { resolve } from 'node:path';
3
3
 
4
- import { CstType, RSToolWrapperClient, type AddOrUpdateConstituentaInput } from '../../src';
4
+ import { CstType, RSToolWrapperClient, type AgentConstituentaPatch } from '../../src';
5
+
6
+ type DraftBatch = { draft: AgentConstituentaPatch };
5
7
 
6
8
  import { DEFAULT_RSFORM_SESSION_PATH } from './constants';
7
9
 
@@ -18,7 +20,7 @@ async function run() {
18
20
  await client.waitUntilReady();
19
21
  const session = await client.call<{ sessionId: string; contractVersion: string }>('createSession');
20
22
 
21
- const drafts: AddOrUpdateConstituentaInput[] = [
23
+ const drafts: DraftBatch[] = [
22
24
  {
23
25
  draft: {
24
26
  id: 1,
@@ -271,22 +273,25 @@ async function run() {
271
273
  }
272
274
  ];
273
275
 
274
- for (const input of drafts) {
275
- const result = await client.call<{
276
- state: { alias: string; analysis: { success: boolean } };
277
- diagnostics: unknown[];
278
- }>('addOrUpdateConstituenta', {
279
- sessionId: session.sessionId,
280
- input
281
- });
282
- const ok = result.state.analysis.success;
283
- const diagCount = result.diagnostics?.length ?? 0;
284
- console.log(`${input.draft.alias}: ${ok ? 'OK' : 'FAIL'} (${diagCount} diagnostics)`);
285
- if (!ok) {
286
- const diags = await client.call('listDiagnostics', { sessionId: session.sessionId });
287
- console.log(JSON.stringify(diags, null, 2));
288
- throw new Error(`${input.draft.alias}: analysis failed (${diagCount} diagnostics)`);
289
- }
276
+ const patch = await client.call<{
277
+ success: boolean;
278
+ diagnostics: unknown[];
279
+ failed: Array<{ draft: { alias: string }; diagnostics: unknown[] }>;
280
+ summary: { items: Array<{ alias: string; analysisSuccess: boolean }> };
281
+ }>('applySchemaPatch', {
282
+ sessionId: session.sessionId,
283
+ mode: 'atomic',
284
+ items: drafts.map(entry => entry.draft)
285
+ });
286
+
287
+ for (const item of patch.summary.items) {
288
+ console.log(`${item.alias}: ${item.analysisSuccess ? 'OK' : 'FAIL'}`);
289
+ }
290
+ if (!patch.success) {
291
+ const diags = await client.call('listDiagnostics', { sessionId: session.sessionId });
292
+ console.log(JSON.stringify(diags, null, 2));
293
+ const failedAlias = patch.failed[0]?.draft.alias ?? 'unknown';
294
+ throw new Error(`${failedAlias}: analysis failed`);
290
295
  }
291
296
 
292
297
  await client.call('commitStep', {