@api-client/core 0.19.1 → 0.19.3

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 (125) hide show
  1. package/build/src/browser.d.ts +5 -1
  2. package/build/src/browser.d.ts.map +1 -1
  3. package/build/src/browser.js +4 -0
  4. package/build/src/browser.js.map +1 -1
  5. package/build/src/index.d.ts +4 -0
  6. package/build/src/index.d.ts.map +1 -1
  7. package/build/src/index.js +4 -0
  8. package/build/src/index.js.map +1 -1
  9. package/build/src/mocking/ModelingMock.d.ts +2 -0
  10. package/build/src/mocking/ModelingMock.d.ts.map +1 -1
  11. package/build/src/mocking/ModelingMock.js +2 -0
  12. package/build/src/mocking/ModelingMock.js.map +1 -1
  13. package/build/src/mocking/lib/Ai.d.ts +11 -0
  14. package/build/src/mocking/lib/Ai.d.ts.map +1 -0
  15. package/build/src/mocking/lib/Ai.js +53 -0
  16. package/build/src/mocking/lib/Ai.js.map +1 -0
  17. package/build/src/modeling/ai/DataDomainDelta.d.ts +146 -0
  18. package/build/src/modeling/ai/DataDomainDelta.d.ts.map +1 -0
  19. package/build/src/modeling/ai/DataDomainDelta.js +729 -0
  20. package/build/src/modeling/ai/DataDomainDelta.js.map +1 -0
  21. package/build/src/modeling/ai/DomainSerialization.d.ts +20 -0
  22. package/build/src/modeling/ai/DomainSerialization.d.ts.map +1 -0
  23. package/build/src/modeling/ai/DomainSerialization.js +185 -0
  24. package/build/src/modeling/ai/DomainSerialization.js.map +1 -0
  25. package/build/src/modeling/ai/domain_response_schema.d.ts +806 -0
  26. package/build/src/modeling/ai/domain_response_schema.d.ts.map +1 -0
  27. package/build/src/modeling/ai/domain_response_schema.js +289 -0
  28. package/build/src/modeling/ai/domain_response_schema.js.map +1 -0
  29. package/build/src/modeling/ai/domain_tools.d.ts +68 -0
  30. package/build/src/modeling/ai/domain_tools.d.ts.map +1 -0
  31. package/build/src/modeling/ai/domain_tools.js +71 -0
  32. package/build/src/modeling/ai/domain_tools.js.map +1 -0
  33. package/build/src/modeling/ai/index.d.ts +10 -0
  34. package/build/src/modeling/ai/index.d.ts.map +1 -0
  35. package/build/src/modeling/ai/index.js +9 -0
  36. package/build/src/modeling/ai/index.js.map +1 -0
  37. package/build/src/modeling/ai/message_parser.d.ts +23 -0
  38. package/build/src/modeling/ai/message_parser.d.ts.map +1 -0
  39. package/build/src/modeling/ai/message_parser.js +93 -0
  40. package/build/src/modeling/ai/message_parser.js.map +1 -0
  41. package/build/src/modeling/ai/prompts/domain_system.d.ts +6 -0
  42. package/build/src/modeling/ai/prompts/domain_system.d.ts.map +1 -0
  43. package/build/src/modeling/ai/prompts/domain_system.js +80 -0
  44. package/build/src/modeling/ai/prompts/domain_system.js.map +1 -0
  45. package/build/src/modeling/ai/tools/DataDomain.tools.d.ts +25 -0
  46. package/build/src/modeling/ai/tools/DataDomain.tools.d.ts.map +1 -0
  47. package/build/src/modeling/ai/tools/DataDomain.tools.js +334 -0
  48. package/build/src/modeling/ai/tools/DataDomain.tools.js.map +1 -0
  49. package/build/src/modeling/ai/tools/Semantic.tools.d.ts +48 -0
  50. package/build/src/modeling/ai/tools/Semantic.tools.d.ts.map +1 -0
  51. package/build/src/modeling/ai/tools/Semantic.tools.js +36 -0
  52. package/build/src/modeling/ai/tools/Semantic.tools.js.map +1 -0
  53. package/build/src/modeling/ai/tools/config.d.ts +13 -0
  54. package/build/src/modeling/ai/tools/config.d.ts.map +1 -0
  55. package/build/src/modeling/ai/tools/config.js +2 -0
  56. package/build/src/modeling/ai/tools/config.js.map +1 -0
  57. package/build/src/modeling/ai/types.d.ts +302 -0
  58. package/build/src/modeling/ai/types.d.ts.map +1 -0
  59. package/build/src/modeling/ai/types.js +40 -0
  60. package/build/src/modeling/ai/types.js.map +1 -0
  61. package/build/src/models/AiMessage.d.ts +185 -0
  62. package/build/src/models/AiMessage.d.ts.map +1 -0
  63. package/build/src/models/AiMessage.js +203 -0
  64. package/build/src/models/AiMessage.js.map +1 -0
  65. package/build/src/models/AiSession.d.ts +80 -0
  66. package/build/src/models/AiSession.d.ts.map +1 -0
  67. package/build/src/models/AiSession.js +102 -0
  68. package/build/src/models/AiSession.js.map +1 -0
  69. package/build/src/models/kinds.d.ts +2 -0
  70. package/build/src/models/kinds.d.ts.map +1 -1
  71. package/build/src/models/kinds.js +2 -0
  72. package/build/src/models/kinds.js.map +1 -1
  73. package/build/src/sdk/AiSdk.d.ts +93 -0
  74. package/build/src/sdk/AiSdk.d.ts.map +1 -0
  75. package/build/src/sdk/AiSdk.js +348 -0
  76. package/build/src/sdk/AiSdk.js.map +1 -0
  77. package/build/src/sdk/RouteBuilder.d.ts +7 -0
  78. package/build/src/sdk/RouteBuilder.d.ts.map +1 -1
  79. package/build/src/sdk/RouteBuilder.js +18 -0
  80. package/build/src/sdk/RouteBuilder.js.map +1 -1
  81. package/build/src/sdk/Sdk.d.ts +2 -0
  82. package/build/src/sdk/Sdk.d.ts.map +1 -1
  83. package/build/src/sdk/Sdk.js +2 -0
  84. package/build/src/sdk/Sdk.js.map +1 -1
  85. package/build/src/sdk/SdkBase.d.ts +4 -0
  86. package/build/src/sdk/SdkBase.d.ts.map +1 -1
  87. package/build/src/sdk/SdkBase.js.map +1 -1
  88. package/build/src/sdk/SdkMock.d.ts +15 -0
  89. package/build/src/sdk/SdkMock.d.ts.map +1 -1
  90. package/build/src/sdk/SdkMock.js +118 -0
  91. package/build/src/sdk/SdkMock.js.map +1 -1
  92. package/build/tsconfig.tsbuildinfo +1 -1
  93. package/data/models/example-generator-api.json +22 -22
  94. package/package.json +3 -3
  95. package/src/mocking/ModelingMock.ts +2 -0
  96. package/src/mocking/lib/Ai.ts +71 -0
  97. package/src/modeling/ai/DataDomainDelta.ts +798 -0
  98. package/src/modeling/ai/DomainSerialization.ts +199 -0
  99. package/src/modeling/ai/domain_response_schema.ts +301 -0
  100. package/src/modeling/ai/domain_tools.ts +76 -0
  101. package/src/modeling/ai/message_parser.ts +101 -0
  102. package/src/modeling/ai/prompts/domain_system.ts +79 -0
  103. package/src/modeling/ai/readme.md +8 -0
  104. package/src/modeling/ai/tools/DataDomain.tools.ts +365 -0
  105. package/src/modeling/ai/tools/Semantic.tools.ts +38 -0
  106. package/src/modeling/ai/tools/config.ts +13 -0
  107. package/src/modeling/ai/tools/readme.md +3 -0
  108. package/src/modeling/ai/types.ts +306 -0
  109. package/src/models/AiMessage.ts +335 -0
  110. package/src/models/AiSession.ts +160 -0
  111. package/src/models/kinds.ts +2 -0
  112. package/src/sdk/AiSdk.ts +395 -0
  113. package/src/sdk/RouteBuilder.ts +27 -0
  114. package/src/sdk/Sdk.ts +3 -0
  115. package/src/sdk/SdkBase.ts +4 -0
  116. package/src/sdk/SdkMock.ts +185 -0
  117. package/tests/unit/mocking/current/Ai.spec.ts +109 -0
  118. package/tests/unit/modeling/ai/DataDomainDelta.spec.ts +419 -0
  119. package/tests/unit/modeling/ai/DomainAiTools.spec.ts +29 -0
  120. package/tests/unit/modeling/ai/DomainSerialization.spec.ts +143 -0
  121. package/tests/unit/modeling/ai/message_parser.spec.ts +157 -0
  122. package/tests/unit/modeling/ai/tools/DataDomain.tools.spec.ts +64 -0
  123. package/tests/unit/modeling/ai/tools/Semantic.tools.spec.ts +55 -0
  124. package/tests/unit/models/AiMessage.spec.ts +216 -0
  125. package/tests/unit/models/AiSession.spec.ts +147 -0
@@ -0,0 +1,199 @@
1
+ import type { DataDomain } from '../DataDomain.js'
2
+ import type { DomainNamespace } from '../DomainNamespace.js'
3
+ import type {
4
+ AiDataDomainSchema,
5
+ AiDomainAssociation,
6
+ AiDomainEntityResponseSchema,
7
+ AiDomainEntitySchema,
8
+ AiDomainProperty,
9
+ AiDomainSemantic,
10
+ } from './types.js'
11
+ import type { DomainAssociation, DomainEntity, DomainProperty } from '../index.js'
12
+
13
+ function serializeProperty(prop: DomainProperty): AiDomainProperty {
14
+ const result: AiDomainProperty = {
15
+ key: prop.key,
16
+ type: prop.type,
17
+ }
18
+ if (prop.info.name) {
19
+ result.name = prop.info.name
20
+ }
21
+ if (prop.info.displayName) {
22
+ result.displayName = prop.info.displayName
23
+ }
24
+ if (prop.info.description) {
25
+ result.description = prop.info.description
26
+ }
27
+ if (Array.isArray(prop.semantics) && prop.semantics.length > 0) {
28
+ result.semantics = prop.semantics.map((s) => {
29
+ const res: AiDomainSemantic = { id: s.id }
30
+ if (s.config) res.config = { ...s.config }
31
+ return res
32
+ })
33
+ }
34
+ result.constraints = {}
35
+ if (typeof prop.required === 'boolean') {
36
+ result.constraints.required = prop.required
37
+ }
38
+ if (typeof prop.unique === 'boolean') {
39
+ result.constraints.unique = prop.unique
40
+ }
41
+ if (typeof prop.index === 'boolean') {
42
+ result.constraints.index = prop.index
43
+ }
44
+ if (typeof prop.primary === 'boolean') {
45
+ result.constraints.primary = prop.primary
46
+ }
47
+ if (typeof prop.multiple === 'boolean') {
48
+ result.constraints.multiple = prop.multiple
49
+ }
50
+ if (typeof prop.readOnly === 'boolean') {
51
+ result.constraints.readOnly = prop.readOnly
52
+ }
53
+ if (typeof prop.writeOnly === 'boolean') {
54
+ result.constraints.writeOnly = prop.writeOnly
55
+ }
56
+ if (typeof prop.deprecated === 'boolean') {
57
+ result.deprecated = prop.deprecated
58
+ }
59
+ if (prop.schema) {
60
+ result.schema = { ...prop.schema }
61
+ }
62
+ return result
63
+ }
64
+
65
+ function serializeAssociation(assoc: DomainAssociation): AiDomainAssociation {
66
+ const result: AiDomainAssociation = {
67
+ key: assoc.key,
68
+ targets: [],
69
+ }
70
+ if (assoc.info.name) {
71
+ result.name = assoc.info.name
72
+ }
73
+ if (assoc.info.displayName) {
74
+ result.displayName = assoc.info.displayName
75
+ }
76
+ if (assoc.info.description) {
77
+ result.description = assoc.info.description
78
+ }
79
+ if (Array.isArray(assoc.semantics) && assoc.semantics.length > 0) {
80
+ result.semantics = assoc.semantics.map((s) => {
81
+ const res: AiDomainSemantic = { id: s.id }
82
+ if (s.config) res.config = { ...s.config }
83
+ return res
84
+ })
85
+ }
86
+ if (typeof assoc.required === 'boolean') {
87
+ result.required = assoc.required
88
+ }
89
+ if (typeof assoc.onDelete === 'string') {
90
+ result.onDelete = assoc.onDelete
91
+ }
92
+ if (assoc.schema) {
93
+ result.schema = { ...assoc.schema }
94
+ }
95
+ return result
96
+ }
97
+
98
+ /**
99
+ * Serializes an entity to an AI domain entity response schema.
100
+ * It is used by the `get_entity_details` tool to send a serialized entity information to the AI.
101
+ *
102
+ * @param entity The entity to serialize.
103
+ * @param modelKey The key of the model the entity belongs to.
104
+ * @returns The AI domain entity response schema.
105
+ */
106
+ export function serializeEntity(entity: DomainEntity, modelKey: string): AiDomainEntityResponseSchema {
107
+ const result: AiDomainEntityResponseSchema = {
108
+ key: entity.key,
109
+ modelKey,
110
+ }
111
+ if (entity.info.name) {
112
+ result.name = entity.info.name
113
+ }
114
+ if (entity.info.displayName) {
115
+ result.displayName = entity.info.displayName
116
+ }
117
+ if (entity.info.description) {
118
+ result.description = entity.info.description
119
+ }
120
+ if (Array.isArray(entity.tags) && entity.tags.length > 0) {
121
+ result.tags = [...entity.tags]
122
+ }
123
+ if (Array.isArray(entity.semantics) && entity.semantics.length > 0) {
124
+ result.semantics = entity.semantics.map((s) => {
125
+ const res: AiDomainSemantic = { id: s.id }
126
+ if (s.config) res.config = { ...s.config }
127
+ return res
128
+ })
129
+ }
130
+ result.properties = []
131
+ for (const prop of entity.listProperties()) {
132
+ result.properties.push(serializeProperty(prop))
133
+ }
134
+ result.associations = []
135
+ for (const assoc of entity.listAssociations()) {
136
+ result.associations.push(serializeAssociation(assoc))
137
+ }
138
+ return result
139
+ }
140
+
141
+ /**
142
+ * Serializes an entity to a minimal AI domain entity schema.
143
+ *
144
+ * @param entity The entity to serialize.
145
+ * @param modelKey The key of the model the entity belongs to.
146
+ * @returns The AI domain entity schema.
147
+ */
148
+ function serializeEntityMinimal(entity: DomainEntity, modelKey: string): AiDomainEntitySchema {
149
+ const result: AiDomainEntitySchema = {
150
+ key: entity.key,
151
+ modelKey,
152
+ }
153
+ if (entity.info.name) {
154
+ result.name = entity.info.name
155
+ }
156
+ if (entity.info.description) {
157
+ result.description = entity.info.description
158
+ }
159
+ return result
160
+ }
161
+
162
+ /**
163
+ * Processes a namespace and serializes its models and entities to the schema sent to the AI endpoint.
164
+ * @param ns The namespace to process.
165
+ * @param result The result schema to add the models and entities to.
166
+ */
167
+ function processNamespace(ns: DomainNamespace | DataDomain, result: AiDataDomainSchema): void {
168
+ for (const childNs of ns.listNamespaces()) {
169
+ processNamespace(childNs, result)
170
+ }
171
+ for (const model of ns.listModels()) {
172
+ result.models.push({
173
+ key: model.key,
174
+ name: model.info.name || model.info.displayName || model.key,
175
+ description: model.info.description,
176
+ })
177
+ for (const entity of model.listEntities()) {
178
+ result.entities.push(serializeEntityMinimal(entity, model.key))
179
+ }
180
+ }
181
+ }
182
+
183
+ /**
184
+ * Serializes a data domain to a minimal AI domain schema.
185
+ * It is used to serialize the domain to send it to the AI endpoint.
186
+ * @param domain The data domain to serialize.
187
+ * @returns The AI domain schema.
188
+ */
189
+ export function serializeDomainForAi(domain: DataDomain): AiDataDomainSchema {
190
+ const result: AiDataDomainSchema = {
191
+ key: domain.key,
192
+ name: domain.info.name || domain.info.displayName || 'Unnamed Domain',
193
+ models: [],
194
+ entities: [],
195
+ }
196
+
197
+ processNamespace(domain, result)
198
+ return result
199
+ }
@@ -0,0 +1,301 @@
1
+ import { Type } from './types.js'
2
+
3
+ const SemanticSchema = {
4
+ type: Type.OBJECT,
5
+ properties: {
6
+ id: { type: Type.STRING },
7
+ config: { type: Type.OBJECT },
8
+ },
9
+ required: ['id'],
10
+ }
11
+
12
+ const SchemaDefaultValue = {
13
+ type: Type.OBJECT,
14
+ properties: {
15
+ type: {
16
+ type: Type.STRING,
17
+ description: 'Enum: literal, function',
18
+ },
19
+ value: {
20
+ type: Type.STRING,
21
+ description: 'The default value of the property',
22
+ },
23
+ },
24
+ required: ['type'],
25
+ }
26
+
27
+ const PropertySchemaShape = {
28
+ type: Type.OBJECT,
29
+ properties: {
30
+ minimum: { type: Type.NUMBER },
31
+ maximum: { type: Type.NUMBER },
32
+ exclusiveMinimum: { type: Type.BOOLEAN },
33
+ exclusiveMaximum: { type: Type.BOOLEAN },
34
+ multipleOf: { type: Type.NUMBER },
35
+ enum: { type: Type.ARRAY, items: { type: Type.STRING } },
36
+ examples: { type: Type.ARRAY, items: { type: Type.STRING } },
37
+ defaultValue: SchemaDefaultValue,
38
+ pattern: { type: Type.STRING },
39
+ },
40
+ }
41
+
42
+ const PropertyConstraintsSchema = {
43
+ type: Type.OBJECT,
44
+ properties: {
45
+ required: { type: Type.BOOLEAN },
46
+ unique: { type: Type.BOOLEAN },
47
+ index: { type: Type.BOOLEAN },
48
+ primary: { type: Type.BOOLEAN },
49
+ multiple: { type: Type.BOOLEAN },
50
+ readOnly: { type: Type.BOOLEAN },
51
+ writeOnly: { type: Type.BOOLEAN },
52
+ },
53
+ }
54
+
55
+ /**
56
+ * Must comply with the `AiDomainProperty` type.
57
+ */
58
+ const PropertySchema = {
59
+ type: Type.OBJECT,
60
+ properties: {
61
+ key: { type: Type.STRING },
62
+ name: { type: Type.STRING },
63
+ displayName: { type: Type.STRING },
64
+ description: { type: Type.STRING },
65
+ type: {
66
+ type: Type.STRING,
67
+ description: 'Enum: string, number, boolean, date, datetime, time, binary',
68
+ },
69
+ constraints: PropertyConstraintsSchema,
70
+ deprecated: { type: Type.BOOLEAN },
71
+ schema: PropertySchemaShape,
72
+ semantics: {
73
+ type: Type.ARRAY,
74
+ items: SemanticSchema,
75
+ description: "List of semantics applied to this property. Note: ONLY use semantics with scope='property'.",
76
+ },
77
+ tags: { type: Type.ARRAY, items: { type: Type.STRING } },
78
+ },
79
+ required: ['key', 'name', 'type', 'displayName', 'description'],
80
+ }
81
+
82
+ const AssociationSchemaShape = {
83
+ type: Type.OBJECT,
84
+ properties: {
85
+ linked: { type: Type.BOOLEAN },
86
+ unionType: { type: Type.STRING, description: 'Enum: allOf, anyOf, oneOf, not' },
87
+ },
88
+ }
89
+
90
+ /**
91
+ * Must comply with the `AiDomainAssociation` type.
92
+ */
93
+ const AssociationSchema = {
94
+ type: Type.OBJECT,
95
+ properties: {
96
+ key: { type: Type.STRING },
97
+ name: { type: Type.STRING },
98
+ displayName: { type: Type.STRING },
99
+ description: { type: Type.STRING },
100
+ targets: { type: Type.ARRAY, items: { type: Type.STRING }, description: 'List of target entity keys' },
101
+ required: { type: Type.BOOLEAN },
102
+ multiple: {
103
+ type: Type.BOOLEAN,
104
+ description: 'Whether the association can have multiple targets (like User has multiple addresses)',
105
+ },
106
+ onDelete: { type: Type.STRING, description: 'Enum: restrict, cascade, setNull, doNothing' },
107
+ semantics: {
108
+ type: Type.ARRAY,
109
+ items: SemanticSchema,
110
+ description: "List of semantics applied to this association. Note: ONLY use semantics with scope='association'.",
111
+ },
112
+ schema: AssociationSchemaShape,
113
+ },
114
+ required: ['key', 'name', 'targets', 'displayName', 'description'],
115
+ }
116
+
117
+ /**
118
+ * Must comply with the `AiDataModel` type.
119
+ */
120
+ const ModelSchema = {
121
+ type: Type.OBJECT,
122
+ properties: {
123
+ key: { type: Type.STRING },
124
+ name: { type: Type.STRING },
125
+ description: { type: Type.STRING },
126
+ },
127
+ required: ['key', 'name'],
128
+ }
129
+
130
+ /**
131
+ * Must comply with the `AiDomainEntityResponseSchema` type.
132
+ */
133
+ const EntitySchema = {
134
+ type: Type.OBJECT,
135
+ properties: {
136
+ key: { type: Type.STRING },
137
+ modelKey: { type: Type.STRING, description: 'The Domain Model this entity belongs to (e.g. "users", "shipping")' },
138
+ name: { type: Type.STRING },
139
+ displayName: { type: Type.STRING },
140
+ description: { type: Type.STRING },
141
+ tags: { type: Type.ARRAY, items: { type: Type.STRING } },
142
+ semantics: {
143
+ type: Type.ARRAY,
144
+ items: SemanticSchema,
145
+ description: "List of semantics applied to this entity. Note: ONLY use semantics with scope='entity'.",
146
+ },
147
+ properties: { type: Type.ARRAY, items: PropertySchema },
148
+ associations: { type: Type.ARRAY, items: AssociationSchema },
149
+ },
150
+ required: ['key', 'name', 'modelKey', 'displayName', 'description'],
151
+ }
152
+
153
+ const PropertyDeltaSchema = {
154
+ type: Type.OBJECT,
155
+ properties: {
156
+ key: { type: Type.STRING },
157
+ name: { type: Type.STRING },
158
+ displayName: { type: Type.STRING },
159
+ description: { type: Type.STRING },
160
+ type: {
161
+ type: Type.STRING,
162
+ description: 'Enum: string, number, boolean, date, datetime, time, binary',
163
+ },
164
+ constraints: PropertyConstraintsSchema,
165
+ deprecated: { type: Type.BOOLEAN },
166
+ schema: PropertySchemaShape,
167
+ addedSemantics: {
168
+ type: Type.ARRAY,
169
+ items: SemanticSchema,
170
+ description: "Semantics to add. Note: ONLY use semantics with scope='property'.",
171
+ },
172
+ modifiedSemantics: { type: Type.ARRAY, items: SemanticSchema },
173
+ deletedSemanticIds: { type: Type.ARRAY, items: { type: Type.STRING } },
174
+ },
175
+ required: ['key'],
176
+ }
177
+
178
+ const AssociationDeltaSchema = {
179
+ type: Type.OBJECT,
180
+ properties: {
181
+ key: { type: Type.STRING },
182
+ name: { type: Type.STRING },
183
+ displayName: { type: Type.STRING },
184
+ description: { type: Type.STRING },
185
+ targets: { type: Type.ARRAY, items: { type: Type.STRING } },
186
+ required: { type: Type.BOOLEAN },
187
+ multiple: {
188
+ type: Type.BOOLEAN,
189
+ description: 'Whether the association can have multiple targets (like User has multiple addresses)',
190
+ },
191
+ onDelete: { type: Type.STRING, description: 'Enum: restrict, cascade, setNull, doNothing' },
192
+ addedSemantics: {
193
+ type: Type.ARRAY,
194
+ items: SemanticSchema,
195
+ description: "Semantics to add. Note: ONLY use semantics with scope='association'.",
196
+ },
197
+ modifiedSemantics: { type: Type.ARRAY, items: SemanticSchema },
198
+ deletedSemanticIds: { type: Type.ARRAY, items: { type: Type.STRING } },
199
+ },
200
+ required: ['key'],
201
+ }
202
+
203
+ /**
204
+ * Must comply with the `AiDomainDeltaResponse` type.
205
+ */
206
+ export const DOMAIN_SCHEMA = {
207
+ type: Type.OBJECT,
208
+ properties: {
209
+ sessionTitle: {
210
+ type: Type.STRING,
211
+ description: 'A short, 3-to-5 word descriptive title for this data modeling session.',
212
+ },
213
+ reasoning: {
214
+ type: Type.STRING,
215
+ description: 'Conversational response analyzing the request or explaining changes, in markdown format',
216
+ },
217
+ delta: {
218
+ type: Type.OBJECT,
219
+ properties: {
220
+ addedModels: {
221
+ type: Type.ARRAY,
222
+ items: ModelSchema,
223
+ description: 'Brand new models to create',
224
+ },
225
+ deletedModelKeys: {
226
+ type: Type.ARRAY,
227
+ items: { type: Type.STRING },
228
+ description:
229
+ 'Keys of completely removed models. This also removes all entities and associations in the model.',
230
+ },
231
+ modifiedModels: {
232
+ type: Type.ARRAY,
233
+ items: ModelSchema,
234
+ description: 'Models to modify in the domain',
235
+ },
236
+ addedEntities: {
237
+ type: Type.ARRAY,
238
+ items: EntitySchema,
239
+ description: 'Brand new entities to create',
240
+ },
241
+ deletedEntityKeys: {
242
+ type: Type.ARRAY,
243
+ items: { type: Type.STRING },
244
+ description: 'Keys of completely removed entities',
245
+ },
246
+ modifiedEntities: {
247
+ type: Type.ARRAY,
248
+ items: {
249
+ type: Type.OBJECT,
250
+ properties: {
251
+ key: { type: Type.STRING, description: 'The original key of the existing entity being modified' },
252
+ modelKey: {
253
+ type: Type.STRING,
254
+ description: 'Change this to migrate the entity to a different model (boundary)',
255
+ },
256
+ name: { type: Type.STRING },
257
+ displayName: { type: Type.STRING },
258
+ description: { type: Type.STRING },
259
+ tags: { type: Type.ARRAY, items: { type: Type.STRING } },
260
+ addedSemantics: {
261
+ type: Type.ARRAY,
262
+ items: SemanticSchema,
263
+ description: "Semantics to add. Note: ONLY use semantics with scope='entity'.",
264
+ },
265
+ modifiedSemantics: { type: Type.ARRAY, items: SemanticSchema },
266
+ deletedSemanticIds: { type: Type.ARRAY, items: { type: Type.STRING } },
267
+ addedProperties: { type: Type.ARRAY, items: PropertySchema },
268
+ modifiedProperties: { type: Type.ARRAY, items: PropertyDeltaSchema },
269
+ deletedPropertyKeys: { type: Type.ARRAY, items: { type: Type.STRING } },
270
+ addedAssociations: { type: Type.ARRAY, items: AssociationSchema },
271
+ modifiedAssociations: { type: Type.ARRAY, items: AssociationDeltaSchema },
272
+ deletedAssociationKeys: { type: Type.ARRAY, items: { type: Type.STRING } },
273
+ },
274
+ required: [
275
+ 'key',
276
+ // 'addedSemantics',
277
+ // 'modifiedSemantics',
278
+ // 'deletedSemanticIds',
279
+ // 'addedProperties',
280
+ // 'modifiedProperties',
281
+ // 'deletedPropertyKeys',
282
+ // 'addedAssociations',
283
+ // 'modifiedAssociations',
284
+ // 'deletedAssociationKeys',
285
+ ],
286
+ },
287
+ description: 'Modifications to existing entities like adding, removing, or changing properties/associations',
288
+ },
289
+ },
290
+ required: [
291
+ 'addedModels',
292
+ 'deletedModelKeys',
293
+ 'modifiedModels',
294
+ 'addedEntities',
295
+ 'deletedEntityKeys',
296
+ 'modifiedEntities',
297
+ ],
298
+ },
299
+ },
300
+ required: ['reasoning', 'delta'],
301
+ }
@@ -0,0 +1,76 @@
1
+ import { Type } from './types.js'
2
+ import { get_semantic_details, list_semantics } from './tools/Semantic.tools.js'
3
+ import { explain_schema, get_entity_details } from './tools/DataDomain.tools.js'
4
+ import { ToolConfig } from './tools/config.js'
5
+
6
+ /**
7
+ * All tools available for the AI to use when modeling a domain.
8
+ */
9
+ export const tools = [
10
+ {
11
+ functionDeclarations: [
12
+ {
13
+ name: 'list_semantics',
14
+ description: 'List all available data semantics, their scopes, and whether they have configuration options.',
15
+ parametersJsonSchema: {
16
+ type: Type.OBJECT,
17
+ properties: {},
18
+ required: [],
19
+ },
20
+ },
21
+ {
22
+ name: 'get_semantic_details',
23
+ description:
24
+ 'Get detailed information about a specific data semantic, notably its JSON ' +
25
+ 'configuration schema properties, to determine what additional config you might want to provide.',
26
+ parametersJsonSchema: {
27
+ type: Type.OBJECT,
28
+ properties: {
29
+ semanticId: {
30
+ type: Type.STRING,
31
+ description: 'The exact ID of the semantic (e.g. Semantic#Password, Semantic#Tags)',
32
+ },
33
+ },
34
+ required: ['semanticId'],
35
+ },
36
+ },
37
+ {
38
+ name: 'get_entity_details',
39
+ description: 'Get the full details of an entity given its key, including properties, associations, and tags.',
40
+ parametersJsonSchema: {
41
+ type: Type.OBJECT,
42
+ properties: {
43
+ entityKey: {
44
+ type: Type.STRING,
45
+ description: 'The exact key/ID of the entity to fetch details for.',
46
+ },
47
+ },
48
+ required: ['entityKey'],
49
+ },
50
+ },
51
+ {
52
+ name: 'explain_schema',
53
+ description: 'Explains the schema of a data type.',
54
+ parametersJsonSchema: {
55
+ type: Type.OBJECT,
56
+ properties: {
57
+ dataType: {
58
+ type: Type.STRING,
59
+ description: 'The data type (e.g. string, number, boolean, date, datetime, time, binary)',
60
+ },
61
+ },
62
+ required: ['dataType'],
63
+ },
64
+ },
65
+ ],
66
+ },
67
+ ]
68
+
69
+ export type ToolFunction = (config: ToolConfig, args: Record<string, unknown>) => unknown | Promise<unknown>
70
+
71
+ export const functions: Record<string, ToolFunction> = {
72
+ list_semantics,
73
+ get_semantic_details,
74
+ explain_schema,
75
+ get_entity_details,
76
+ }
@@ -0,0 +1,101 @@
1
+ import type { AiModelMessageWithDelta } from './types.js'
2
+ import type { AiMessageSchema, AiUserMessage } from '../../models/AiMessage.js'
3
+ import { DataDomainDelta } from './DataDomainDelta.js'
4
+
5
+ /**
6
+ * Parses an incoming `AiMessage` and maps it directly into its runtime
7
+ * representations `AiUserMessage` or `AiModelMessageWithDelta`.
8
+ *
9
+ * If the message is a model message, it attempts to parse the structured JSON
10
+ * contents in `msg.text` and sets the `delta` field accordingly. The `text` field
11
+ * is replaced with the reasoning text, or remains original if parsing fails/is omitted.
12
+ *
13
+ * @param msg The generic AI chat message.
14
+ * @returns The parsed in-memory wrapper context message.
15
+ */
16
+ export function parseAiChatMessage(msg: AiMessageSchema): AiUserMessage | AiModelMessageWithDelta {
17
+ if (msg.role === 'user') {
18
+ return msg as AiUserMessage
19
+ }
20
+
21
+ const modelMsg = { ...msg } as AiModelMessageWithDelta
22
+
23
+ // Try to parse the delta structure
24
+ if (modelMsg.state === 'complete' && modelMsg.text) {
25
+ try {
26
+ const parsedJSON = JSON.parse(modelMsg.text)
27
+ modelMsg.delta = parsedJSON.delta ? DataDomainDelta.normalize(parsedJSON.delta) : undefined
28
+ modelMsg.text = parsedJSON.reasoning || modelMsg.text
29
+ } catch {
30
+ // It might legitimately not be valid JSON yet if it crashed mid-stream,
31
+ // fallback to retaining original shape.
32
+ }
33
+ }
34
+
35
+ return modelMsg
36
+ }
37
+
38
+ /**
39
+ * When a model response is generated it may contain the `reasoning` property. But because
40
+ * that property might still be generated it might not be a valid JSON. This function checks
41
+ * if the text contains reasoning and returns it if it does.
42
+ * @param text The text to check.
43
+ * @returns The reasoning string if it exists, otherwise undefined.
44
+ */
45
+ export function detectReasoning(text: string): string | undefined {
46
+ try {
47
+ const parsedJSON = JSON.parse(text)
48
+ return parsedJSON.reasoning
49
+ } catch {
50
+ // Continue below
51
+ }
52
+
53
+ const searchStr = '"reasoning"'
54
+ const keyIndex = text.indexOf(searchStr)
55
+ if (keyIndex === -1) {
56
+ return undefined
57
+ }
58
+
59
+ const afterKey = text.substring(keyIndex + searchStr.length)
60
+ const colonIndex = afterKey.indexOf(':')
61
+ if (colonIndex === -1) {
62
+ return undefined
63
+ }
64
+
65
+ const afterColon = afterKey.substring(colonIndex + 1)
66
+ const quoteIndex = afterColon.indexOf('"')
67
+ if (quoteIndex === -1) {
68
+ return undefined
69
+ }
70
+
71
+ const valueStr = afterColon.substring(quoteIndex + 1)
72
+ let isEscaped = false
73
+ let endIndex = -1
74
+
75
+ for (let i = 0; i < valueStr.length; i++) {
76
+ const char = valueStr[i]
77
+ if (char === '\\' && !isEscaped) {
78
+ isEscaped = true
79
+ } else if (char === '"' && !isEscaped) {
80
+ endIndex = i
81
+ break
82
+ } else {
83
+ isEscaped = false
84
+ }
85
+ }
86
+
87
+ const extracted = endIndex !== -1 ? valueStr.substring(0, endIndex) : valueStr
88
+
89
+ try {
90
+ // Try to safely parse the literal string value.
91
+ return JSON.parse('"' + extracted + '"')
92
+ } catch {
93
+ // string replace fallback
94
+ return extracted
95
+ .replace(/\\n/g, '\n')
96
+ .replace(/\\r/g, '\r')
97
+ .replace(/\\t/g, '\t')
98
+ .replace(/\\"/g, '"')
99
+ .replace(/\\\\/g, '\\')
100
+ }
101
+ }