agentlang 0.0.5 → 0.0.7

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 (77) hide show
  1. package/out/language/generated/ast.d.ts +7 -7
  2. package/out/language/generated/ast.d.ts.map +1 -1
  3. package/out/language/generated/ast.js +1 -1
  4. package/out/language/generated/ast.js.map +1 -1
  5. package/out/language/generated/grammar.js +5 -5
  6. package/out/language/main.cjs +6 -6
  7. package/out/language/main.cjs.map +2 -2
  8. package/out/language/parser.d.ts.map +1 -1
  9. package/out/language/parser.js +21 -5
  10. package/out/language/parser.js.map +1 -1
  11. package/out/language/syntax.d.ts +8 -2
  12. package/out/language/syntax.d.ts.map +1 -1
  13. package/out/language/syntax.js +42 -2
  14. package/out/language/syntax.js.map +1 -1
  15. package/out/runtime/agents/common.d.ts +1 -1
  16. package/out/runtime/agents/common.d.ts.map +1 -1
  17. package/out/runtime/agents/common.js +48 -0
  18. package/out/runtime/agents/common.js.map +1 -1
  19. package/out/runtime/agents/impl/openai.js +1 -1
  20. package/out/runtime/agents/impl/openai.js.map +1 -1
  21. package/out/runtime/auth/cognito.d.ts +2 -0
  22. package/out/runtime/auth/cognito.d.ts.map +1 -1
  23. package/out/runtime/auth/cognito.js +115 -15
  24. package/out/runtime/auth/cognito.js.map +1 -1
  25. package/out/runtime/auth/interface.d.ts +2 -0
  26. package/out/runtime/auth/interface.d.ts.map +1 -1
  27. package/out/runtime/interpreter.d.ts.map +1 -1
  28. package/out/runtime/interpreter.js +64 -16
  29. package/out/runtime/interpreter.js.map +1 -1
  30. package/out/runtime/jsmodules.d.ts +6 -0
  31. package/out/runtime/jsmodules.d.ts.map +1 -0
  32. package/out/runtime/jsmodules.js +138 -0
  33. package/out/runtime/jsmodules.js.map +1 -0
  34. package/out/runtime/loader.d.ts.map +1 -1
  35. package/out/runtime/loader.js +11 -11
  36. package/out/runtime/loader.js.map +1 -1
  37. package/out/runtime/module.d.ts +14 -1
  38. package/out/runtime/module.d.ts.map +1 -1
  39. package/out/runtime/module.js +96 -17
  40. package/out/runtime/module.js.map +1 -1
  41. package/out/runtime/modules/ai.d.ts +1 -0
  42. package/out/runtime/modules/ai.d.ts.map +1 -1
  43. package/out/runtime/modules/ai.js +20 -11
  44. package/out/runtime/modules/ai.js.map +1 -1
  45. package/out/runtime/modules/auth.d.ts +7 -3
  46. package/out/runtime/modules/auth.d.ts.map +1 -1
  47. package/out/runtime/modules/auth.js +129 -8
  48. package/out/runtime/modules/auth.js.map +1 -1
  49. package/out/runtime/resolvers/interface.d.ts +0 -1
  50. package/out/runtime/resolvers/interface.d.ts.map +1 -1
  51. package/out/runtime/resolvers/interface.js.map +1 -1
  52. package/out/runtime/resolvers/sqldb/impl.d.ts.map +1 -1
  53. package/out/runtime/resolvers/sqldb/impl.js +9 -3
  54. package/out/runtime/resolvers/sqldb/impl.js.map +1 -1
  55. package/out/runtime/util.d.ts +0 -4
  56. package/out/runtime/util.d.ts.map +1 -1
  57. package/out/runtime/util.js +0 -78
  58. package/out/runtime/util.js.map +1 -1
  59. package/package.json +1 -1
  60. package/src/language/agentlang.langium +3 -4
  61. package/src/language/generated/ast.ts +8 -8
  62. package/src/language/generated/grammar.ts +5 -5
  63. package/src/language/parser.ts +24 -5
  64. package/src/language/syntax.ts +50 -5
  65. package/src/runtime/agents/common.ts +48 -0
  66. package/src/runtime/agents/impl/openai.ts +1 -1
  67. package/src/runtime/auth/cognito.ts +152 -22
  68. package/src/runtime/auth/interface.ts +7 -0
  69. package/src/runtime/interpreter.ts +63 -18
  70. package/src/runtime/jsmodules.ts +123 -0
  71. package/src/runtime/loader.ts +11 -10
  72. package/src/runtime/module.ts +113 -18
  73. package/src/runtime/modules/ai.ts +22 -14
  74. package/src/runtime/modules/auth.ts +156 -8
  75. package/src/runtime/resolvers/interface.ts +0 -1
  76. package/src/runtime/resolvers/sqldb/impl.ts +8 -3
  77. package/src/runtime/util.ts +0 -70
@@ -44,6 +44,7 @@ import {
44
44
  import { parseStatement } from '../language/parser.js';
45
45
  import { ActiveSessionInfo, AdminSession } from './auth/defs.js';
46
46
  import { DefaultIdAttributeName, PathAttributeName } from './defs.js';
47
+ import { logger } from './logger.js';
47
48
 
48
49
  export class ModuleEntry {
49
50
  name: string;
@@ -101,7 +102,7 @@ function recordSchemaToString(scm: RecordSchema): string {
101
102
  ss.push(` ${n} ${attributeSpecToString(attrSpec)}`);
102
103
  }
103
104
  });
104
- return `\n${ss.join(',\n')} \n`;
105
+ return `\n${ss.join(',\n')}`;
105
106
  }
106
107
 
107
108
  function attributeSpecToString(attrSpec: AttributeSpec): string {
@@ -142,7 +143,7 @@ function normalizeMetaValue(metaValue: any): any {
142
143
  const v: Literal = metaValue as Literal;
143
144
  if (v.array) {
144
145
  return v.array.vals.map((value: Statement) => {
145
- return normalizeMetaValue(value.pattern.literal);
146
+ return normalizeMetaValue(value.pattern.expr);
146
147
  });
147
148
  } else if (v.bool != undefined) {
148
149
  return v.bool;
@@ -177,6 +178,23 @@ function asTriggerInfo(te: TriggerEntry): TriggerInfo {
177
178
  };
178
179
  }
179
180
 
181
+ const EnumPropertyName = 'one-of';
182
+ const OneOfPropertyName = 'one-of-ref';
183
+
184
+ export function enumAttributeSpec(values: Set<string>): AttributeSpec {
185
+ return {
186
+ type: 'String',
187
+ properties: new Map().set(EnumPropertyName, values),
188
+ };
189
+ }
190
+
191
+ export function oneOfAttributeSpec(ref: string): AttributeSpec {
192
+ return {
193
+ type: 'String',
194
+ properties: new Map().set(OneOfPropertyName, ref),
195
+ };
196
+ }
197
+
180
198
  export class Record extends ModuleEntry {
181
199
  schema: RecordSchema;
182
200
  meta: Meta | undefined;
@@ -241,9 +259,9 @@ export class Record extends ModuleEntry {
241
259
  }
242
260
  if (isArrayType) props.set('array', true);
243
261
  if (isObjectType) props.set('object', true);
244
- if (enumValues) props.set('one-of', new Set(enumValues));
262
+ if (enumValues) props.set(EnumPropertyName, new Set(enumValues));
245
263
  if (oneOfRef) {
246
- props.set('one-of-ref', oneOfRef);
264
+ props.set(OneOfPropertyName, oneOfRef);
247
265
  this.addOneOfRefAttribute(a.name);
248
266
  }
249
267
  }
@@ -424,9 +442,9 @@ export class Record extends ModuleEntry {
424
442
  const rbs = this.rbac.map((rs: RbacSpecification) => {
425
443
  return rs.toString();
426
444
  });
427
- scms = `${scms} @rbac [${rbs.join(',\n')}]`;
445
+ scms = `${scms},\n @rbac [${rbs.join(',\n')}]`;
428
446
  }
429
- return s.concat('\n{', scms, '}\n');
447
+ return s.concat('\n{', scms, '\n}\n');
430
448
  }
431
449
 
432
450
  getUserAttributes(): RecordSchema {
@@ -532,7 +550,7 @@ function normalizeKvPairValue(kvp: KvPair): any | null {
532
550
  } else if (v.num != undefined) {
533
551
  return v.num;
534
552
  } else if (v.bool != undefined) {
535
- return v.bool;
553
+ return v.bool == 'true' ? true : false;
536
554
  } else if (v.id != undefined) {
537
555
  return v.id;
538
556
  } else if (v.ref != undefined) {
@@ -602,14 +620,16 @@ export class RbacSpecification {
602
620
  }
603
621
 
604
622
  setPermissions(perms: Array<string>): RbacSpecification {
623
+ const ps = new Set<RbacPermissionFlag>();
605
624
  perms.forEach((v: string) => {
606
625
  const idx: any = v.toUpperCase();
607
626
  const a: any = RbacPermissionFlag[idx];
608
627
  if (a == undefined) {
609
628
  throw new Error(`Not a valid RBAC permission - ${v}`);
610
629
  }
611
- this.permissions.add(a);
630
+ ps.add(a);
612
631
  });
632
+ this.permissions = ps;
613
633
  return this;
614
634
  }
615
635
 
@@ -644,9 +664,15 @@ export class RbacSpecification {
644
664
  return this;
645
665
  }
646
666
 
667
+ removeRoles(): RbacSpecification {
668
+ this.roles = RbacSpecification.EmptyRoles;
669
+ return this;
670
+ }
671
+
647
672
  setExpression(lhs: string, rhs: string): RbacSpecification {
648
673
  if (this.roles != RbacSpecification.EmptyRoles) {
649
- throw new Error('Cannot set `where` expression along with roles');
674
+ logger.warn('Cannot set `where` expression along with roles, removing roles');
675
+ this.removeRoles();
650
676
  }
651
677
  this.expression = {
652
678
  lhs: lhs,
@@ -655,7 +681,15 @@ export class RbacSpecification {
655
681
  return this;
656
682
  }
657
683
 
684
+ removeExpression(): RbacSpecification {
685
+ this.expression = undefined;
686
+ return this;
687
+ }
688
+
658
689
  toString(): string {
690
+ if (this.permissions.size <= 0) {
691
+ throw new Error(`Cannot emit RbacSpecification, no permissions are set`);
692
+ }
659
693
  const rs = new Array<string>();
660
694
  this.roles.forEach((r: string) => {
661
695
  rs.push(r);
@@ -875,6 +909,10 @@ function asRelNodeEntry(n: NodeDefinition): RelationshipNode {
875
909
  };
876
910
  }
877
911
 
912
+ const OneToOne = 'one_one';
913
+ const OneToMany = 'one_many';
914
+ const ManyToMany = 'many_many';
915
+
878
916
  export class Relationship extends Record {
879
917
  override type: RecordType = RecordType.RELATIONSHIP;
880
918
  relType: RelType = RelType.CONTAINS;
@@ -953,25 +991,52 @@ export class Relationship extends Record {
953
991
  return false;
954
992
  }
955
993
 
994
+ private setProperty(p: string, v: any): Relationship {
995
+ if (this.properties == undefined) {
996
+ this.properties = new Map();
997
+ }
998
+ this.properties.set(p, v);
999
+ return this;
1000
+ }
1001
+
956
1002
  isOneToOne(): boolean {
957
- return this.isBetween() && this.hasBooleanFlagSet('one_one');
1003
+ return this.isBetween() && this.hasBooleanFlagSet(OneToOne);
958
1004
  }
959
1005
 
960
1006
  isOneToMany(): boolean {
961
- return this.isBetween() && this.hasBooleanFlagSet('one_many');
1007
+ return this.isBetween() && this.hasBooleanFlagSet(OneToMany);
962
1008
  }
963
1009
 
964
1010
  isManyToMany(): boolean {
965
1011
  if (this.isBetween()) {
966
1012
  return (
967
- this.hasBooleanFlagSet('many_many') ||
968
- (!this.hasBooleanFlagSet('one_one') && !this.hasBooleanFlagSet('one_many'))
1013
+ this.hasBooleanFlagSet(ManyToMany) ||
1014
+ (!this.hasBooleanFlagSet(OneToOne) && !this.hasBooleanFlagSet(OneToMany))
969
1015
  );
970
1016
  } else {
971
1017
  return false;
972
1018
  }
973
1019
  }
974
1020
 
1021
+ setOneToOne(flag: boolean = true): Relationship {
1022
+ if (flag) {
1023
+ this.setOneToMany(false).setManyToMany(false);
1024
+ }
1025
+ return this.setProperty(OneToOne, flag);
1026
+ }
1027
+
1028
+ setOneToMany(flag: boolean = true): Relationship {
1029
+ if (flag) {
1030
+ this.setOneToOne(false).setManyToMany(false);
1031
+ }
1032
+ return this.setProperty(OneToMany, flag);
1033
+ }
1034
+
1035
+ setManyToMany(flag: boolean = true): Relationship {
1036
+ this.setOneToOne(false).setOneToMany(false);
1037
+ return this.setProperty(ManyToMany, flag);
1038
+ }
1039
+
975
1040
  isFirstNode(inst: Instance): boolean {
976
1041
  return this.isFirstNodeName(inst.getFqName());
977
1042
  }
@@ -1561,22 +1626,46 @@ function getAnyProperty(propName: string, attrSpec: AttributeSpec): any | undefi
1561
1626
  return undefined;
1562
1627
  }
1563
1628
 
1629
+ function setAnyProperty(propName: string, value: any, attrSpec: AttributeSpec): AttributeSpec {
1630
+ if (attrSpec.properties == undefined) {
1631
+ attrSpec.properties = new Map();
1632
+ }
1633
+ attrSpec.properties.set(propName, value);
1634
+ return attrSpec;
1635
+ }
1636
+
1564
1637
  export function isIdAttribute(attrSpec: AttributeSpec): boolean {
1565
1638
  return getBooleanProperty('id', attrSpec);
1566
1639
  }
1567
1640
 
1641
+ export function asIdAttribute(attrSpec: AttributeSpec): AttributeSpec {
1642
+ return setAnyProperty('id', true, attrSpec);
1643
+ }
1644
+
1568
1645
  export function isUniqueAttribute(attrSpec: AttributeSpec): boolean {
1569
1646
  return getBooleanProperty('unique', attrSpec);
1570
1647
  }
1571
1648
 
1649
+ export function asUniqueAttribute(attrSpec: AttributeSpec): AttributeSpec {
1650
+ return setAnyProperty('unique', true, attrSpec);
1651
+ }
1652
+
1572
1653
  export function isIndexedAttribute(attrSpec: AttributeSpec): boolean {
1573
1654
  return getBooleanProperty('indexed', attrSpec);
1574
1655
  }
1575
1656
 
1657
+ export function asIndexedAttribute(attrSpec: AttributeSpec): AttributeSpec {
1658
+ return setAnyProperty('indexed', true, attrSpec);
1659
+ }
1660
+
1576
1661
  export function isOptionalAttribute(attrSpec: AttributeSpec): boolean {
1577
1662
  return getBooleanProperty('optional', attrSpec);
1578
1663
  }
1579
1664
 
1665
+ export function asOptionalAttribute(attrSpec: AttributeSpec): AttributeSpec {
1666
+ return setAnyProperty('optional', true, attrSpec);
1667
+ }
1668
+
1580
1669
  export function isArrayAttribute(attrSpec: AttributeSpec): boolean {
1581
1670
  return getBooleanProperty('array', attrSpec);
1582
1671
  }
@@ -1601,6 +1690,10 @@ export function getAttributeDefaultValue(attrSpec: AttributeSpec): any | undefin
1601
1690
  return getAnyProperty('default', attrSpec);
1602
1691
  }
1603
1692
 
1693
+ export function setDefaultAttributeValue(attrSpec: AttributeSpec, value: any): AttributeSpec {
1694
+ return setAnyProperty('default', value, attrSpec);
1695
+ }
1696
+
1604
1697
  export function getAttributeLength(attrSpec: AttributeSpec): number | undefined {
1605
1698
  return getAnyProperty('length', attrSpec);
1606
1699
  }
@@ -2212,12 +2305,14 @@ export class Instance {
2212
2305
  }
2213
2306
  }
2214
2307
 
2215
- export function objectAsInstanceAttributes(obj: object): InstanceAttributes {
2308
+ export function objectAsInstanceAttributes(obj: object | undefined): InstanceAttributes {
2216
2309
  const attrs: InstanceAttributes = newInstanceAttributes();
2217
- Object.entries(obj).forEach((v: [string, any]) => {
2218
- const obj = v[1];
2219
- attrs.set(v[0], obj);
2220
- });
2310
+ if (obj) {
2311
+ Object.entries(obj).forEach((v: [string, any]) => {
2312
+ const obj = v[1];
2313
+ attrs.set(v[0], obj);
2314
+ });
2315
+ }
2221
2316
  return attrs;
2222
2317
  }
2223
2318
 
@@ -12,6 +12,7 @@ import {
12
12
  import { AIMessage, BaseMessage, HumanMessage } from '@langchain/core/messages';
13
13
  import { PlannerInstructions } from '../agents/common.js';
14
14
  import { PathAttributeNameQuery } from '../defs.js';
15
+ import { logger } from '../logger.js';
15
16
 
16
17
  export const CoreAIModuleName = makeCoreModuleName('ai');
17
18
  export const AgentEntityName = 'Agent';
@@ -28,6 +29,7 @@ entity ${LlmEntityName} {
28
29
  entity ${AgentEntityName} {
29
30
  name String @id,
30
31
  type @enum("chat", "planner") @default("chat"),
32
+ runWorkflows Boolean @default(true),
31
33
  instruction String @optional,
32
34
  tools String @optional, // comma-separated values
33
35
  documents String @optional, // comma-separated values
@@ -67,6 +69,7 @@ export class AgentInstance {
67
69
  type: string = 'chat';
68
70
  tools: string | undefined;
69
71
  documents: string | undefined;
72
+ runWorkflows: boolean = true;
70
73
 
71
74
  private constructor() {}
72
75
 
@@ -91,21 +94,26 @@ export class AgentInstance {
91
94
  msgs = [systemMessage(this.instruction)];
92
95
  }
93
96
  if (msgs) {
94
- const sysMsg = msgs[0];
95
- if (isplnr) {
96
- const newSysMsg = systemMessage(
97
- `${PlannerInstructions}\n${this.toolsAsString()}\n${this.instruction}`
98
- );
99
- msgs[0] = newSysMsg;
100
- }
101
- msgs.push(humanMessage(await this.maybeAddRelevantDocuments(message, env)));
102
- const response: AIResponse = await p.invoke(msgs);
103
- msgs.push(assistantMessage(response.content));
104
- if (isplnr) {
105
- msgs[0] = sysMsg;
97
+ try {
98
+ const sysMsg = msgs[0];
99
+ if (isplnr) {
100
+ const newSysMsg = systemMessage(
101
+ `${PlannerInstructions}\n${this.toolsAsString()}\n${this.instruction}`
102
+ );
103
+ msgs[0] = newSysMsg;
104
+ }
105
+ msgs.push(humanMessage(await this.maybeAddRelevantDocuments(message, env)));
106
+ const response: AIResponse = await p.invoke(msgs);
107
+ msgs.push(assistantMessage(response.content));
108
+ if (isplnr) {
109
+ msgs[0] = sysMsg;
110
+ }
111
+ await saveAgentChatSession(chatId, msgs, env);
112
+ env.setLastResult(response.content);
113
+ } catch (err: any) {
114
+ logger.error(`Error while invoking ${agentName} - ${err}`);
115
+ env.setLastResult(undefined);
106
116
  }
107
- await saveAgentChatSession(chatId, msgs, env);
108
- env.setLastResult(response.content);
109
117
  } else {
110
118
  throw new Error(`failed to initialize messages for agent ${agentName}`);
111
119
  }
@@ -130,6 +130,8 @@ entity Session {
130
130
  id UUID @id,
131
131
  userId UUID @indexed,
132
132
  authToken String @optional,
133
+ accessToken String @optional,
134
+ refreshToken String @optional,
133
135
  isActive Boolean,
134
136
  @rbac [(allow: [read, delete, update, create], where: auth.user = this.userId)]
135
137
  }
@@ -137,7 +139,18 @@ entity Session {
137
139
 
138
140
  workflow CreateSession {
139
141
  {Session {id CreateSession.id, userId CreateSession.userId,
140
- authToken CreateSession.authToken, isActive true}}
142
+ authToken CreateSession.authToken,
143
+ accessToken CreateSession.accessToken,
144
+ refreshToken CreateSession.refreshToken,
145
+ isActive true}}
146
+ }
147
+
148
+ workflow UpdateSession {
149
+ {Session {id? UpdateSession.id,
150
+ authToken UpdateSession.authToken,
151
+ accessToken UpdateSession.accessToken,
152
+ refreshToken UpdateSession.refreshToken,
153
+ isActive true}, @upsert}
141
154
  }
142
155
 
143
156
  workflow FindSession {
@@ -146,7 +159,7 @@ workflow FindSession {
146
159
  }
147
160
 
148
161
  workflow FindUserSession {
149
- {Session {userId? FindUserSession.id}} as [session];
162
+ {Session {userId? FindUserSession.userId}} as [session];
150
163
  session
151
164
  }
152
165
 
@@ -167,6 +180,18 @@ workflow login {
167
180
  await Auth.loginUser(login.email, login.password)
168
181
  }
169
182
 
183
+ workflow logout {
184
+ await Auth.logoutUser()
185
+ }
186
+
187
+ workflow changePassword {
188
+ await Auth.changePassword(changePassword.newPassword, changePassword.password)
189
+ }
190
+
191
+ workflow refreshToken {
192
+ await Auth.refreshUserToken(refreshToken.refreshToken)
193
+ }
194
+
170
195
  workflow getUser {
171
196
  await Auth.getUserInfo(getUser.userId)
172
197
  }
@@ -230,18 +255,32 @@ export async function ensureUser(
230
255
  return await createUser(crypto.randomUUID(), email, firstName, lastName, env);
231
256
  }
232
257
 
233
- export async function ensureUserSession(userId: string, token: string, env: Environment) {
258
+ export async function ensureUserSession(
259
+ userId: string,
260
+ token: string,
261
+ accessToken: string,
262
+ refreshToken: string,
263
+ env: Environment
264
+ ): Promise<Instance> {
234
265
  const sess: Instance = await findUserSession(userId, env);
235
266
  if (sess) {
236
- await removeSession(sess.lookup('id'), env);
267
+ // Update existing session instead of deleting and recreating
268
+ await updateSession(sess.lookup('id'), token, accessToken, refreshToken, env);
269
+ // Return the updated session by finding it again
270
+ return await findUserSession(userId, env);
237
271
  }
238
- return await createSession(crypto.randomUUID(), userId, token, env);
272
+ const sessionId = crypto.randomUUID();
273
+ await createSession(sessionId, userId, token, accessToken, refreshToken, env);
274
+ // Return the created session by finding it
275
+ return await findSession(sessionId, env);
239
276
  }
240
277
 
241
278
  export async function createSession(
242
279
  id: string,
243
280
  userId: string,
244
281
  token: string,
282
+ accessToken: string,
283
+ refreshToken: string,
245
284
  env: Environment
246
285
  ): Promise<Result> {
247
286
  return await evalEvent(
@@ -250,6 +289,8 @@ export async function createSession(
250
289
  id: id,
251
290
  userId: userId,
252
291
  authToken: token,
292
+ accessToken: accessToken,
293
+ refreshToken: refreshToken,
253
294
  },
254
295
  env
255
296
  );
@@ -275,6 +316,25 @@ export async function findUserSession(userId: string, env: Environment): Promise
275
316
  );
276
317
  }
277
318
 
319
+ export async function updateSession(
320
+ id: string,
321
+ token: string,
322
+ accessToken: string,
323
+ refreshToken: string,
324
+ env: Environment
325
+ ): Promise<Result> {
326
+ return await evalEvent(
327
+ 'UpdateSession',
328
+ {
329
+ id: id,
330
+ authToken: token,
331
+ accessToken: accessToken,
332
+ refreshToken: refreshToken,
333
+ },
334
+ env
335
+ );
336
+ }
337
+
278
338
  export async function removeSession(id: string, env: Environment): Promise<Result> {
279
339
  return await evalEvent(
280
340
  'RemoveSession',
@@ -539,6 +599,61 @@ export async function loginUser(
539
599
  }
540
600
  }
541
601
 
602
+ async function logoutSession(userId: string, sess: Instance, env: Environment): Promise<string> {
603
+ const sessId = sess.lookup('id');
604
+ const tok = sess.lookup('authToken');
605
+ await fetchAuthImpl().logout(
606
+ {
607
+ sessionId: sessId,
608
+ userId: userId,
609
+ authToken: tok,
610
+ idToken: tok,
611
+ accessToken: sess.lookup('accessToken'),
612
+ refreshToken: sess.lookup('refreshToken'),
613
+ },
614
+ env
615
+ );
616
+ await removeSession(sessId, env);
617
+ return 'ok';
618
+ }
619
+
620
+ export async function logoutUser(env: Environment): Promise<string | undefined> {
621
+ const user = env.getActiveUser();
622
+ const sess = await findUserSession(user, env);
623
+ if (sess) {
624
+ return await logoutSession(user, sess, env);
625
+ }
626
+ return undefined;
627
+ }
628
+
629
+ export async function changePassword(
630
+ newPassword: string,
631
+ password: string,
632
+ env: Environment
633
+ ): Promise<string | undefined> {
634
+ const user = env.getActiveUser();
635
+ const sess = await findUserSession(user, env);
636
+ if (sess) {
637
+ const sessId = sess.lookup('id');
638
+ const tok = sess.lookup('authToken');
639
+ const sessInfo = {
640
+ sessionId: sessId,
641
+ userId: user,
642
+ authToken: tok,
643
+ idToken: tok,
644
+ accessToken: sess.lookup('accessToken'),
645
+ refreshToken: sess.lookup('refreshToken'),
646
+ };
647
+ if (await fetchAuthImpl().changePassword(sessInfo, newPassword, password, env)) {
648
+ return await logoutSession(user, sess, env);
649
+ } else {
650
+ return undefined;
651
+ }
652
+ } else {
653
+ throw new UnauthorisedError(`No active session for user ${user}`);
654
+ }
655
+ }
656
+
542
657
  export async function verifySession(token: string, env?: Environment): Promise<ActiveSessionInfo> {
543
658
  if (!isAuthEnabled()) return BypassSession;
544
659
 
@@ -598,9 +713,12 @@ async function verifyJwtToken(token: string, env?: Environment): Promise<ActiveS
598
713
 
599
714
  // Use the local user's ID for consistency
600
715
  const localUserId = localUser.lookup('id');
601
-
716
+ const sess = await findUserSession(localUserId, env);
717
+ if (!sess) {
718
+ throw new UnauthorisedError(`No session found for user ${email}, UserId: ${userId}`);
719
+ }
602
720
  // For JWT tokens, we use the token itself as sessionId for tracking
603
- return { sessionId: token.substring(0, 32), userId: localUserId };
721
+ return { sessionId: sess.lookup('id'), userId: localUserId };
604
722
  } catch (err: any) {
605
723
  if (err instanceof UnauthorisedError) {
606
724
  throw err;
@@ -690,8 +808,38 @@ export async function getUserInfoByEmail(email: string, env: Environment): Promi
690
808
  }
691
809
  }
692
810
 
811
+ export async function refreshUserToken(refreshToken: string, env: Environment): Promise<object> {
812
+ const needCommit = env ? false : true;
813
+ env = env ? env : new Environment();
814
+ const f = async () => {
815
+ try {
816
+ const sessionInfo = await fetchAuthImpl().refreshToken(refreshToken, env);
817
+
818
+ return {
819
+ id_token: sessionInfo.idToken,
820
+ access_token: sessionInfo.accessToken,
821
+ refresh_token: sessionInfo.refreshToken,
822
+ token_type: 'Bearer',
823
+ expires_in: 3600,
824
+ userId: sessionInfo.userId,
825
+ sessionId: sessionInfo.sessionId,
826
+ };
827
+ } catch (err: any) {
828
+ logger.error(`Token refresh failed: ${err.message}`);
829
+ throw err;
830
+ }
831
+ };
832
+ if (needCommit) {
833
+ return await env.callInTransaction(f);
834
+ } else {
835
+ return await f();
836
+ }
837
+ }
838
+
693
839
  export function requireAuth(moduleName: string, eventName: string): boolean {
694
- const f = moduleName == CoreAuthModuleName && (eventName == 'login' || eventName == 'signup');
840
+ const f =
841
+ moduleName == CoreAuthModuleName &&
842
+ (eventName == 'login' || eventName == 'signup' || eventName == 'refreshToken');
695
843
  return !f;
696
844
  }
697
845
 
@@ -217,7 +217,6 @@ export type GenericResolverMethods = {
217
217
 
218
218
  export type GenericResolverSubscription = {
219
219
  subscribe: MaybeFunction;
220
- onSubscriptionEvent: string;
221
220
  };
222
221
 
223
222
  export class GenericResolver extends Resolver {
@@ -40,6 +40,7 @@ import { Environment } from '../../interpreter.js';
40
40
  import { OpenAIEmbeddings } from '@langchain/openai';
41
41
  import { Embeddings } from '@langchain/core/embeddings';
42
42
  import { DeletedFlagAttributeName, ParentAttributeName, PathAttributeName } from '../../defs.js';
43
+ import { logger } from '../../logger.js';
43
44
 
44
45
  function maybeFindIdAttributeName(inst: Instance): string | undefined {
45
46
  const attrEntry: AttributeEntry | undefined = findIdAttribute(inst);
@@ -108,9 +109,13 @@ export class SqlDbResolver extends Resolver {
108
109
  await insertRow(n, rowObj, ctx, orUpdate);
109
110
  if (inst.record.getFullTextSearchAttributes()) {
110
111
  const path = attrs.get(PathAttributeName);
111
- if (!(await vectorStoreSearchEntryExists(n, path, ctx))) {
112
- const res = await this.embeddings.embedQuery(JSON.stringify(rowObj));
113
- await addRowForFullTextSearch(n, path, res, ctx);
112
+ try {
113
+ if (!(await vectorStoreSearchEntryExists(n, path, ctx))) {
114
+ const res = await this.embeddings.embedQuery(JSON.stringify(rowObj));
115
+ await addRowForFullTextSearch(n, path, res, ctx);
116
+ }
117
+ } catch (reason: any) {
118
+ logger.warn(`Full text indexing failed for ${path} - ${reason}`);
114
119
  }
115
120
  }
116
121
  return inst;
@@ -11,7 +11,6 @@ import {
11
11
  Statement,
12
12
  } from '../language/generated/ast.js';
13
13
  import { readFile } from '../utils/fs-utils.js';
14
- import { logger } from './logger.js';
15
14
 
16
15
  export const QuerySuffix = '?';
17
16
 
@@ -27,75 +26,6 @@ if (isNodeEnv) {
27
26
  promisify = nu.promisify;
28
27
  }
29
28
 
30
- const importedModules = new Map<string, any>();
31
-
32
- // Usage: importModule("./mymodels/acme.js")
33
- export async function importModule(path: string, name: string) {
34
- const m = await import(/* @vite-ignore */ path);
35
- importedModules.set(name, m);
36
- // e.g of dynamic fn-call:
37
- //// let f = eval("(a, b) => m.add(a, b)");
38
- //// console.log(f(10, 20))
39
- return m;
40
- }
41
-
42
- export function moduleImported(moduleName: string): boolean {
43
- return importedModules.has(moduleName);
44
- }
45
-
46
- function maybeEvalFunction(fnName: string): Function | undefined {
47
- try {
48
- return eval(fnName);
49
- } catch (reason: any) {
50
- logger.debug(reason);
51
- return undefined;
52
- }
53
- }
54
-
55
- export async function invokeModuleFn(
56
- fqFnName: string,
57
- args: Array<any> | null,
58
- isAsync: boolean = false
59
- ): Promise<any> {
60
- try {
61
- const refs: string[] = splitRefs(fqFnName);
62
- const m = importedModules.get(refs[0]);
63
- if (m != undefined) {
64
- const f = m[refs[1]];
65
- if (f != undefined) {
66
- if (args == null)
67
- if (isAsync) {
68
- return await f();
69
- } else return f();
70
- else if (isAsync) {
71
- return await f(...args);
72
- } else return f(...args);
73
- } else throw new Error(`Function not found - ${fqFnName}`);
74
- } else throw new Error(`JavaScript module ${refs[0]} not found`);
75
- } catch (reason: any) {
76
- const pf: Function | undefined = maybeEvalFunction(fqFnName);
77
- if (pf instanceof Function) {
78
- if (args == null) {
79
- if (isAsync) return await pf();
80
- else return pf();
81
- } else {
82
- if (isAsync) return await pf(...args.slice(0, args.length - 1));
83
- else return pf(...args.slice(0, args.length - 1));
84
- }
85
- } else {
86
- throw new Error(reason);
87
- }
88
- }
89
- }
90
-
91
- export function getModuleFn(fqFnName: string): Function | undefined {
92
- const refs: string[] = splitRefs(fqFnName);
93
- const m = importedModules.get(refs[0]);
94
- if (m != undefined) {
95
- return m[refs[1]];
96
- } else return undefined;
97
- }
98
-
99
29
  export function isNumber(x: any): boolean {
100
30
  return typeof x === 'number';
101
31
  }