jaclang 0.5.11__py3-none-any.whl → 0.5.15__py3-none-any.whl

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.

Potentially problematic release.


This version of jaclang might be problematic. Click here for more details.

Files changed (43) hide show
  1. jaclang/cli/cli.py +20 -0
  2. jaclang/compiler/__init__.py +35 -19
  3. jaclang/compiler/absyntree.py +103 -95
  4. jaclang/compiler/generated/jac_parser.py +4069 -0
  5. jaclang/compiler/jac.lark +655 -0
  6. jaclang/compiler/parser.py +44 -31
  7. jaclang/compiler/passes/main/fuse_typeinfo_pass.py +92 -37
  8. jaclang/compiler/passes/main/import_pass.py +8 -5
  9. jaclang/compiler/passes/main/pyast_gen_pass.py +512 -352
  10. jaclang/compiler/passes/main/pyast_load_pass.py +271 -64
  11. jaclang/compiler/passes/main/registry_pass.py +3 -7
  12. jaclang/compiler/passes/main/tests/test_pyast_gen_pass.py +2 -0
  13. jaclang/compiler/passes/main/type_check_pass.py +4 -1
  14. jaclang/compiler/passes/tool/jac_formatter_pass.py +7 -0
  15. jaclang/compiler/passes/tool/tests/test_unparse_validate.py +16 -0
  16. jaclang/compiler/passes/utils/mypy_ast_build.py +93 -0
  17. jaclang/compiler/tests/test_importer.py +15 -0
  18. jaclang/core/aott.py +4 -3
  19. jaclang/core/construct.py +1 -1
  20. jaclang/core/importer.py +109 -51
  21. jaclang/core/llms.py +29 -0
  22. jaclang/core/registry.py +22 -0
  23. jaclang/core/utils.py +72 -0
  24. jaclang/plugin/default.py +118 -6
  25. jaclang/plugin/feature.py +29 -2
  26. jaclang/plugin/spec.py +25 -2
  27. jaclang/utils/helpers.py +7 -9
  28. jaclang/utils/lang_tools.py +37 -13
  29. jaclang/utils/test.py +1 -3
  30. jaclang/utils/tests/test_lang_tools.py +6 -0
  31. jaclang/vendor/lark/grammars/common.lark +59 -0
  32. jaclang/vendor/lark/grammars/lark.lark +62 -0
  33. jaclang/vendor/lark/grammars/python.lark +302 -0
  34. jaclang/vendor/lark/grammars/unicode.lark +7 -0
  35. {jaclang-0.5.11.dist-info → jaclang-0.5.15.dist-info}/METADATA +1 -1
  36. {jaclang-0.5.11.dist-info → jaclang-0.5.15.dist-info}/RECORD +40 -36
  37. jaclang/compiler/__jac_gen__/jac_parser.py +0 -4069
  38. jaclang/compiler/tests/fixtures/__jac_gen__/__init__.py +0 -0
  39. jaclang/compiler/tests/fixtures/__jac_gen__/hello_world.py +0 -5
  40. /jaclang/compiler/{__jac_gen__ → generated}/__init__.py +0 -0
  41. {jaclang-0.5.11.dist-info → jaclang-0.5.15.dist-info}/WHEEL +0 -0
  42. {jaclang-0.5.11.dist-info → jaclang-0.5.15.dist-info}/entry_points.txt +0 -0
  43. {jaclang-0.5.11.dist-info → jaclang-0.5.15.dist-info}/top_level.txt +0 -0
@@ -11,7 +11,7 @@ from typing import Optional, Sequence, TypeVar
11
11
  import jaclang.compiler.absyntree as ast
12
12
  from jaclang.compiler.constant import Constants as Con, EdgeDir, Tokens as Tok
13
13
  from jaclang.compiler.passes import Pass
14
- from jaclang.core.utils import get_sem_scope
14
+ from jaclang.core.utils import extract_params, extract_type, get_sem_scope
15
15
 
16
16
  T = TypeVar("T", bound=ast3.AST)
17
17
 
@@ -19,6 +19,8 @@ T = TypeVar("T", bound=ast3.AST)
19
19
  class PyastGenPass(Pass):
20
20
  """Jac blue transpilation to python pass."""
21
21
 
22
+ cout = 1
23
+
22
24
  @staticmethod
23
25
  def node_compilable_test(node: ast3.AST) -> None:
24
26
  """Convert any AST node to a compilable module node."""
@@ -485,69 +487,117 @@ class PyastGenPass(Pass):
485
487
  sub_module: Optional[Module],
486
488
  """
487
489
  py_nodes: list[ast3.AST] = []
490
+
488
491
  if node.doc:
489
492
  py_nodes.append(
490
493
  self.sync(ast3.Expr(value=node.doc.gen.py_ast[0]), jac_node=node.doc)
491
494
  )
492
495
  py_compat_path_str = []
496
+ path_alias = {}
493
497
  for path in node.paths:
494
498
  py_compat_path_str.append(path.path_str.lstrip("."))
495
- if node.lang.tag.value == Con.JAC_LANG_IMP:
496
- self.needs_jac_import()
497
- for p in range(len(py_compat_path_str)):
498
- py_nodes.append(
499
- self.sync(
500
- ast3.Expr(
501
- value=self.sync(
502
- ast3.Call(
503
- func=self.sync(
504
- ast3.Name(id="__jac_import__", ctx=ast3.Load())
499
+ path_alias[path.path_str] = path.alias.sym_name if path.alias else None
500
+ imp_from = {}
501
+ if node.items:
502
+ for item in node.items.items:
503
+ imp_from[item.name.sym_name] = (
504
+ item.alias.sym_name if item.alias else False
505
+ )
506
+
507
+ keys = []
508
+ values = []
509
+ for k in imp_from.keys():
510
+ keys.append(self.sync(ast3.Constant(value=k)))
511
+ for v in imp_from.values():
512
+ values.append(self.sync(ast3.Constant(value=v)))
513
+
514
+ self.needs_jac_import()
515
+ for p, a in path_alias.items():
516
+ py_nodes.append(
517
+ self.sync(
518
+ ast3.Expr(
519
+ value=self.sync(
520
+ ast3.Call(
521
+ func=self.sync(
522
+ ast3.Name(id="__jac_import__", ctx=ast3.Load())
523
+ ),
524
+ args=[],
525
+ keywords=[
526
+ self.sync(
527
+ ast3.keyword(
528
+ arg="target",
529
+ value=self.sync(
530
+ ast3.Constant(value=p),
531
+ ),
532
+ )
505
533
  ),
506
- args=[],
507
- keywords=[
508
- self.sync(
509
- ast3.keyword(
510
- arg="target",
511
- value=self.sync(
512
- ast3.Constant(
513
- value=node.paths[p].path_str
514
- ),
515
- node.paths[p],
516
- ),
517
- )
518
- ),
519
- self.sync(
520
- ast3.keyword(
521
- arg="base_path",
522
- value=self.sync(
523
- ast3.Name(
524
- id="__file__", ctx=ast3.Load()
525
- )
526
- ),
527
- )
528
- ),
529
- self.sync(
530
- ast3.keyword(
531
- arg="mod_bundle",
532
- value=self.sync(
533
- ast3.Name(
534
- id="__jac_mod_bundle__",
535
- ctx=ast3.Load(),
536
- )
534
+ self.sync(
535
+ ast3.keyword(
536
+ arg="base_path",
537
+ value=self.sync(
538
+ ast3.Name(
539
+ id="__file__", ctx=ast3.Load()
540
+ )
541
+ ),
542
+ )
543
+ ),
544
+ self.sync(
545
+ ast3.keyword(
546
+ arg="mod_bundle",
547
+ value=self.sync(
548
+ ast3.Name(
549
+ id="__jac_mod_bundle__",
550
+ ctx=ast3.Load(),
551
+ )
552
+ ),
553
+ )
554
+ ),
555
+ self.sync(
556
+ ast3.keyword(
557
+ arg="lng",
558
+ value=self.sync(
559
+ ast3.Constant(
560
+ value=node.lang.tag.value
537
561
  ),
538
- )
539
- ),
540
- ],
541
- )
562
+ node.lang,
563
+ ),
564
+ )
565
+ ),
566
+ self.sync(
567
+ ast3.keyword(
568
+ arg="absorb",
569
+ value=self.sync(
570
+ ast3.Constant(value=node.is_absorb),
571
+ ),
572
+ )
573
+ ),
574
+ self.sync(
575
+ ast3.keyword(
576
+ arg="mdl_alias",
577
+ value=self.sync(
578
+ ast3.Constant(value=a),
579
+ ),
580
+ )
581
+ ),
582
+ self.sync(
583
+ ast3.keyword(
584
+ arg="items",
585
+ value=self.sync(
586
+ ast3.Dict(keys=keys, values=values),
587
+ ),
588
+ )
589
+ ),
590
+ ],
542
591
  )
543
- ),
544
- )
592
+ )
593
+ ),
545
594
  )
595
+ )
546
596
  if node.is_absorb:
547
597
  py_nodes.append(
548
598
  self.sync(
549
599
  py_node=ast3.ImportFrom(
550
- module=py_compat_path_str[0],
600
+ module=py_compat_path_str[0] if py_compat_path_str[0] else None,
551
601
  names=[self.sync(ast3.alias(name="*"), node)],
552
602
  level=0,
553
603
  ),
@@ -566,7 +616,7 @@ class PyastGenPass(Pass):
566
616
  py_nodes.append(
567
617
  self.sync(
568
618
  ast3.ImportFrom(
569
- module=py_compat_path_str[0],
619
+ module=py_compat_path_str[0] if py_compat_path_str[0] else None,
570
620
  names=node.items.gen.py_ast,
571
621
  level=0,
572
622
  )
@@ -938,318 +988,89 @@ class PyastGenPass(Pass):
938
988
  if isinstance(node.body, ast.AbilityDef):
939
989
  self.link_jac_py_nodes(jac_node=node.body, py_nodes=node.gen.py_ast)
940
990
 
941
- def bfs_collect_type(self, node: ast.AstNode) -> list[str]:
942
- """Collect type information in assignment using bfs."""
943
- extracted_type = []
944
- if isinstance(node, (ast.BuiltinType, ast.Token)):
945
- extracted_type.append(node.value)
946
- for child in node.kid:
947
- extracted_type.extend(self.bfs_collect_type(child))
948
- return extracted_type
949
-
950
991
  def gen_llm_body(self, node: ast.Ability) -> list[ast3.AST]:
951
992
  """Generate llm body."""
993
+ self.needs_jac_feature()
952
994
  if isinstance(node.body, ast.FuncCall):
953
- model_params = {}
954
- include_info = []
955
- exclude_info = []
956
- if node.body.params:
957
- for param in node.body.params.items:
958
- if isinstance(param, ast.KWPair) and isinstance(
959
- param.key, ast.Name
960
- ):
961
- key = param.key.value
962
- value = param.value
963
- if key not in ["incl_info", "excl_info"]:
964
- model_params[key] = value
965
- elif key == "incl_info":
966
- if isinstance(value, ast.AtomUnit):
967
- var_name = (
968
- value.value.right.value
969
- if isinstance(value.value, ast.AtomTrailer)
970
- and isinstance(value.value.right, ast.Name)
971
- else (
972
- value.value.value
973
- if isinstance(value.value, ast.Name)
974
- else ""
975
- )
976
- )
977
- include_info.append((var_name, value.gen.py_ast[0]))
978
- elif isinstance(value, ast.TupleVal) and value.values:
979
- for i in value.values.items:
980
- var_name = (
981
- i.right.value
982
- if isinstance(i, ast.AtomTrailer)
983
- and isinstance(i.right, ast.Name)
984
- else (
985
- i.value if isinstance(i, ast.Name) else ""
995
+ model = node.body.target.gen.py_ast[0]
996
+ extracted_type = (
997
+ "".join(extract_type(node.signature.return_type))
998
+ if isinstance(node.signature, ast.FuncSignature)
999
+ and node.signature.return_type
1000
+ else None
1001
+ )
1002
+ scope = self.sync(ast3.Constant(value=str(get_sem_scope(node))))
1003
+ model_params, include_info, exclude_info = extract_params(node.body)
1004
+ inputs = (
1005
+ [
1006
+ self.sync(
1007
+ ast3.Tuple(
1008
+ elts=[
1009
+ (
1010
+ self.sync(
1011
+ ast3.Constant(
1012
+ value=(
1013
+ param.semstr.lit_value
1014
+ if param.semstr
1015
+ else None
1016
+ )
986
1017
  )
987
1018
  )
988
- include_info.append((var_name, i.gen.py_ast[0]))
989
- elif key == "excl_info":
990
- if isinstance(value, ast.AtomUnit):
991
- var_name = (
992
- value.value.right.value
993
- if isinstance(value.value, ast.AtomTrailer)
994
- and isinstance(value.value.right, ast.Name)
995
- else (
996
- value.value.value
997
- if isinstance(value.value, ast.Name)
998
- else ""
1019
+ ),
1020
+ (
1021
+ param.type_tag.tag.gen.py_ast[0]
1022
+ if param.type_tag
1023
+ else None
1024
+ ),
1025
+ self.sync(ast3.Constant(value=param.name.value)),
1026
+ self.sync(
1027
+ ast3.Name(
1028
+ id=param.name.value,
1029
+ ctx=ast3.Load(),
999
1030
  )
1031
+ ),
1032
+ ],
1033
+ ctx=ast3.Load(),
1034
+ )
1035
+ )
1036
+ for param in node.signature.params.items
1037
+ ]
1038
+ if isinstance(node.signature, ast.FuncSignature)
1039
+ and node.signature.params
1040
+ else []
1041
+ )
1042
+ outputs = (
1043
+ [
1044
+ (
1045
+ self.sync(
1046
+ ast3.Constant(
1047
+ value=(
1048
+ node.signature.semstr.lit_value
1049
+ if node.signature.semstr
1050
+ else None
1000
1051
  )
1001
- exclude_info.append((var_name, value.gen.py_ast[0]))
1002
- elif isinstance(value, ast.TupleVal) and value.values:
1003
- for i in value.values.items:
1004
- var_name = (
1005
- i.right.value
1006
- if isinstance(i, ast.AtomTrailer)
1007
- and isinstance(i.right, ast.Name)
1008
- else (
1009
- i.value if isinstance(i, ast.Name) else ""
1010
- )
1011
- )
1012
- exclude_info.append((var_name, i.gen.py_ast[0]))
1013
- extracted = (
1014
- "".join(self.bfs_collect_type(node.signature.return_type))
1052
+ )
1053
+ )
1054
+ ),
1055
+ (self.sync(ast3.Constant(value=(extracted_type)))),
1056
+ ]
1015
1057
  if isinstance(node.signature, ast.FuncSignature)
1016
- and node.signature.return_type
1017
- else None
1058
+ else []
1018
1059
  )
1060
+ action = node.semstr.gen.py_ast[0] if node.semstr else None
1019
1061
  return [
1020
1062
  self.sync(
1021
1063
  ast3.Assign(
1022
1064
  targets=[self.sync(ast3.Name(id="output", ctx=ast3.Store()))],
1023
- value=self.sync(
1024
- ast3.Call(
1025
- func=self.sync(
1026
- ast3.Attribute(
1027
- value=self.sync(
1028
- ast3.Name(
1029
- id=Con.JAC_FEATURE.value,
1030
- ctx=ast3.Load(),
1031
- )
1032
- ),
1033
- attr="with_llm",
1034
- ctx=ast3.Load(),
1035
- )
1036
- ),
1037
- args=[],
1038
- keywords=[
1039
- self.sync(
1040
- ast3.keyword(
1041
- arg="file_loc",
1042
- value=self.sync(
1043
- ast3.Name(
1044
- id="__file__", ctx=ast3.Load()
1045
- )
1046
- ),
1047
- )
1048
- ),
1049
- self.sync(
1050
- ast3.keyword(
1051
- arg="model",
1052
- value=node.body.target.gen.py_ast[0],
1053
- )
1054
- ),
1055
- self.sync(
1056
- ast3.keyword(
1057
- arg="model_params",
1058
- value=self.sync(
1059
- ast3.Dict(
1060
- keys=[
1061
- self.sync(
1062
- ast3.Constant(value=key)
1063
- )
1064
- for key in model_params.keys()
1065
- ],
1066
- values=[
1067
- value.gen.py_ast[0]
1068
- for value in model_params.values()
1069
- ],
1070
- )
1071
- ),
1072
- )
1073
- ),
1074
- self.sync(
1075
- ast3.keyword(
1076
- arg="scope",
1077
- value=(
1078
- self.sync(
1079
- ast3.Constant(
1080
- value=str(get_sem_scope(node))
1081
- )
1082
- )
1083
- ),
1084
- )
1085
- ),
1086
- self.sync(
1087
- ast3.keyword(
1088
- arg="incl_info",
1089
- value=self.sync(
1090
- ast3.List(
1091
- elts=[
1092
- self.sync(
1093
- ast3.Tuple(
1094
- elts=[
1095
- self.sync(
1096
- ast3.Constant(
1097
- value=key
1098
- )
1099
- ),
1100
- value,
1101
- ],
1102
- ctx=ast3.Load(),
1103
- )
1104
- )
1105
- for key, value in include_info
1106
- ],
1107
- ctx=ast3.Load(),
1108
- )
1109
- ),
1110
- )
1111
- ),
1112
- self.sync(
1113
- ast3.keyword(
1114
- arg="excl_info",
1115
- value=self.sync(
1116
- ast3.List(
1117
- elts=[
1118
- self.sync(
1119
- ast3.Tuple(
1120
- elts=[
1121
- self.sync(
1122
- ast3.Constant(
1123
- value=key
1124
- )
1125
- ),
1126
- value,
1127
- ],
1128
- ctx=ast3.Load(),
1129
- )
1130
- )
1131
- for key, value in exclude_info
1132
- ],
1133
- ctx=ast3.Load(),
1134
- )
1135
- ),
1136
- ),
1137
- ),
1138
- self.sync(
1139
- ast3.keyword(
1140
- arg="inputs",
1141
- value=self.sync(
1142
- ast3.List(
1143
- elts=(
1144
- [
1145
- self.sync(
1146
- ast3.Tuple(
1147
- elts=[
1148
- (
1149
- self.sync(
1150
- ast3.Constant(
1151
- value=(
1152
- param.semstr.lit_value
1153
- if param.semstr
1154
- else None
1155
- )
1156
- )
1157
- )
1158
- ),
1159
- (
1160
- param.type_tag.tag.gen.py_ast[
1161
- 0
1162
- ]
1163
- if param.type_tag
1164
- else None
1165
- ),
1166
- self.sync(
1167
- ast3.Constant(
1168
- value=param.name.value
1169
- )
1170
- ),
1171
- self.sync(
1172
- ast3.Name(
1173
- id=param.name.value,
1174
- ctx=ast3.Load(),
1175
- )
1176
- ),
1177
- ],
1178
- ctx=ast3.Load(),
1179
- )
1180
- )
1181
- for param in node.signature.params.items
1182
- ]
1183
- if isinstance(
1184
- node.signature,
1185
- ast.FuncSignature,
1186
- )
1187
- and node.signature.params
1188
- else []
1189
- ),
1190
- ctx=ast3.Load(),
1191
- )
1192
- ),
1193
- )
1194
- ),
1195
- self.sync(
1196
- ast3.keyword(
1197
- arg="outputs",
1198
- value=self.sync(
1199
- ast3.Tuple(
1200
- elts=(
1201
- [
1202
- (
1203
- self.sync(
1204
- ast3.Constant(
1205
- value=(
1206
- node.signature.semstr.lit_value
1207
- if node.signature.semstr
1208
- else None
1209
- )
1210
- )
1211
- )
1212
- ),
1213
- (
1214
- node.signature.return_type.gen.py_ast[
1215
- 0
1216
- ]
1217
- if node.signature.return_type
1218
- else None
1219
- ),
1220
- (
1221
- self.sync(
1222
- ast3.Constant(
1223
- value=(
1224
- extracted
1225
- )
1226
- )
1227
- )
1228
- ),
1229
- ]
1230
- if isinstance(
1231
- node.signature,
1232
- ast.FuncSignature,
1233
- )
1234
- else []
1235
- ),
1236
- ctx=ast3.Load(),
1237
- )
1238
- ),
1239
- )
1240
- ),
1241
- self.sync(
1242
- ast3.keyword(
1243
- arg="action",
1244
- value=(
1245
- node.semstr.gen.py_ast[0]
1246
- if node.semstr
1247
- else None
1248
- ),
1249
- )
1250
- ),
1251
- ],
1252
- )
1065
+ value=self.by_llm_call(
1066
+ model,
1067
+ model_params,
1068
+ scope,
1069
+ inputs,
1070
+ outputs,
1071
+ action,
1072
+ include_info,
1073
+ exclude_info,
1253
1074
  ),
1254
1075
  )
1255
1076
  ),
@@ -1303,6 +1124,149 @@ class PyastGenPass(Pass):
1303
1124
  else:
1304
1125
  return []
1305
1126
 
1127
+ def by_llm_call(
1128
+ self,
1129
+ model: ast3.AST,
1130
+ model_params: dict[str, ast.Expr],
1131
+ scope: ast3.AST,
1132
+ inputs: Sequence[Optional[ast3.AST]],
1133
+ outputs: Sequence[Optional[ast3.AST]] | ast3.Call,
1134
+ action: Optional[ast3.AST],
1135
+ include_info: list[tuple[str, ast3.AST]],
1136
+ exclude_info: list[tuple[str, ast3.AST]],
1137
+ ) -> ast3.Call:
1138
+ """Return the LLM Call, e.g. _Jac.with_llm()."""
1139
+ return self.sync(
1140
+ ast3.Call(
1141
+ func=self.sync(
1142
+ ast3.Attribute(
1143
+ value=self.sync(
1144
+ ast3.Name(
1145
+ id=Con.JAC_FEATURE.value,
1146
+ ctx=ast3.Load(),
1147
+ )
1148
+ ),
1149
+ attr="with_llm",
1150
+ ctx=ast3.Load(),
1151
+ )
1152
+ ),
1153
+ args=[],
1154
+ keywords=[
1155
+ self.sync(
1156
+ ast3.keyword(
1157
+ arg="file_loc",
1158
+ value=self.sync(ast3.Name(id="__file__", ctx=ast3.Load())),
1159
+ )
1160
+ ),
1161
+ self.sync(
1162
+ ast3.keyword(
1163
+ arg="model",
1164
+ value=model,
1165
+ )
1166
+ ),
1167
+ self.sync(
1168
+ ast3.keyword(
1169
+ arg="model_params",
1170
+ value=self.sync(
1171
+ ast3.Dict(
1172
+ keys=[
1173
+ self.sync(ast3.Constant(value=key))
1174
+ for key in model_params.keys()
1175
+ ],
1176
+ values=[
1177
+ value.gen.py_ast[0]
1178
+ for value in model_params.values()
1179
+ ],
1180
+ )
1181
+ ),
1182
+ )
1183
+ ),
1184
+ self.sync(
1185
+ ast3.keyword(
1186
+ arg="scope",
1187
+ value=scope,
1188
+ )
1189
+ ),
1190
+ self.sync(
1191
+ ast3.keyword(
1192
+ arg="incl_info",
1193
+ value=self.sync(
1194
+ ast3.List(
1195
+ elts=[
1196
+ self.sync(
1197
+ ast3.Tuple(
1198
+ elts=[
1199
+ self.sync(ast3.Constant(value=key)),
1200
+ value,
1201
+ ],
1202
+ ctx=ast3.Load(),
1203
+ )
1204
+ )
1205
+ for key, value in include_info
1206
+ ],
1207
+ ctx=ast3.Load(),
1208
+ )
1209
+ ),
1210
+ )
1211
+ ),
1212
+ self.sync(
1213
+ ast3.keyword(
1214
+ arg="excl_info",
1215
+ value=self.sync(
1216
+ ast3.List(
1217
+ elts=[
1218
+ self.sync(
1219
+ ast3.Tuple(
1220
+ elts=[
1221
+ self.sync(ast3.Constant(value=key)),
1222
+ value,
1223
+ ],
1224
+ ctx=ast3.Load(),
1225
+ )
1226
+ )
1227
+ for key, value in exclude_info
1228
+ ],
1229
+ ctx=ast3.Load(),
1230
+ )
1231
+ ),
1232
+ ),
1233
+ ),
1234
+ self.sync(
1235
+ ast3.keyword(
1236
+ arg="inputs",
1237
+ value=self.sync(
1238
+ ast3.List(
1239
+ elts=inputs,
1240
+ ctx=ast3.Load(),
1241
+ )
1242
+ ),
1243
+ )
1244
+ ),
1245
+ self.sync(
1246
+ ast3.keyword(
1247
+ arg="outputs",
1248
+ value=(
1249
+ self.sync(
1250
+ ast3.Tuple(
1251
+ elts=outputs,
1252
+ ctx=ast3.Load(),
1253
+ )
1254
+ )
1255
+ if not isinstance(outputs, ast3.Call)
1256
+ else outputs
1257
+ ),
1258
+ )
1259
+ ),
1260
+ self.sync(
1261
+ ast3.keyword(
1262
+ arg="action",
1263
+ value=action,
1264
+ )
1265
+ ),
1266
+ ],
1267
+ )
1268
+ )
1269
+
1306
1270
  def exit_ability_def(self, node: ast.AbilityDef) -> None:
1307
1271
  """Sub objects.
1308
1272
 
@@ -2302,6 +2266,7 @@ class PyastGenPass(Pass):
2302
2266
  items=[node.left], delim=Tok.COMMA, kid=[node.left]
2303
2267
  )
2304
2268
  ),
2269
+ genai_call=None,
2305
2270
  kid=node.kid,
2306
2271
  )
2307
2272
  self.exit_func_call(func_node)
@@ -2338,6 +2303,7 @@ class PyastGenPass(Pass):
2338
2303
  items=[node.right], delim=Tok.COMMA, kid=[node.right]
2339
2304
  )
2340
2305
  ),
2306
+ genai_call=None,
2341
2307
  kid=node.kid,
2342
2308
  )
2343
2309
  self.exit_func_call(func_node)
@@ -2737,7 +2703,10 @@ class PyastGenPass(Pass):
2737
2703
  right: AtomExpr | Expr,
2738
2704
  is_attr: bool,
2739
2705
  is_null_ok: bool,
2706
+ is_genai: bool = False,
2740
2707
  """
2708
+ if node.is_genai:
2709
+ node.gen.py_ast = []
2741
2710
  if node.is_attr:
2742
2711
  if isinstance(node.right, ast.AstSymbolNode):
2743
2712
  node.gen.py_ast = [
@@ -2850,9 +2819,200 @@ class PyastGenPass(Pass):
2850
2819
  keywords.append(x.gen.py_ast[0])
2851
2820
  else:
2852
2821
  self.ice("Invalid Parameter")
2853
- node.gen.py_ast = [
2854
- self.sync(ast3.Call(func=func, args=args, keywords=keywords))
2855
- ]
2822
+ if node.genai_call:
2823
+ self.needs_jac_feature()
2824
+ model = node.genai_call.target.gen.py_ast[0]
2825
+ model_params, include_info, exclude_info = extract_params(node.genai_call)
2826
+ action = self.sync(
2827
+ ast3.Constant(
2828
+ value="Create an object of the specified type, using the specifically "
2829
+ " provided input value(s) and look up any missing attributes from reliable"
2830
+ " online sources to fill them in accurately."
2831
+ )
2832
+ )
2833
+ _output_ = "".join(extract_type(node.target))
2834
+ include_info.append(
2835
+ (
2836
+ _output_.split(".")[0],
2837
+ self.sync(ast3.Name(id=_output_.split(".")[0], ctx=ast3.Load())),
2838
+ )
2839
+ )
2840
+ scope = self.sync(
2841
+ ast3.Call(
2842
+ func=self.sync(
2843
+ ast3.Attribute(
2844
+ value=self.sync(
2845
+ ast3.Name(
2846
+ id=Con.JAC_FEATURE.value,
2847
+ ctx=ast3.Load(),
2848
+ )
2849
+ ),
2850
+ attr="obj_scope",
2851
+ ctx=ast3.Load(),
2852
+ )
2853
+ ),
2854
+ args=[
2855
+ self.sync(
2856
+ ast3.Name(
2857
+ id="__file__",
2858
+ ctx=ast3.Load(),
2859
+ )
2860
+ ),
2861
+ self.sync(ast3.Constant(value=_output_)),
2862
+ ],
2863
+ keywords=[],
2864
+ )
2865
+ )
2866
+ outputs = self.sync(
2867
+ ast3.Call(
2868
+ func=self.sync(
2869
+ ast3.Attribute(
2870
+ value=self.sync(
2871
+ ast3.Name(
2872
+ id=Con.JAC_FEATURE.value,
2873
+ ctx=ast3.Load(),
2874
+ )
2875
+ ),
2876
+ attr="get_sem_type",
2877
+ ctx=ast3.Load(),
2878
+ )
2879
+ ),
2880
+ args=[
2881
+ self.sync(
2882
+ ast3.Name(
2883
+ id="__file__",
2884
+ ctx=ast3.Load(),
2885
+ )
2886
+ ),
2887
+ self.sync(ast3.Constant(value=str(_output_))),
2888
+ ],
2889
+ keywords=[],
2890
+ )
2891
+ )
2892
+ if node.params and node.params.items:
2893
+ inputs = [
2894
+ self.sync(
2895
+ ast3.Tuple(
2896
+ elts=[
2897
+ self.sync(
2898
+ ast3.Call(
2899
+ func=self.sync(
2900
+ ast3.Attribute(
2901
+ value=self.sync(
2902
+ ast3.Name(
2903
+ id=Con.JAC_FEATURE.value,
2904
+ ctx=ast3.Load(),
2905
+ )
2906
+ ),
2907
+ attr="get_semstr_type",
2908
+ ctx=ast3.Load(),
2909
+ )
2910
+ ),
2911
+ args=[
2912
+ self.sync(
2913
+ ast3.Name(
2914
+ id="__file__", ctx=ast3.Load()
2915
+ )
2916
+ ),
2917
+ scope,
2918
+ self.sync(
2919
+ ast3.Constant(
2920
+ value=(
2921
+ kw_pair.key.value
2922
+ if isinstance(
2923
+ kw_pair.key, ast.Name
2924
+ )
2925
+ else None
2926
+ )
2927
+ )
2928
+ ),
2929
+ self.sync(ast3.Constant(value=True)),
2930
+ ],
2931
+ keywords=[],
2932
+ )
2933
+ ),
2934
+ self.sync(
2935
+ ast3.Call(
2936
+ func=self.sync(
2937
+ ast3.Attribute(
2938
+ value=self.sync(
2939
+ ast3.Name(
2940
+ id=Con.JAC_FEATURE.value,
2941
+ ctx=ast3.Load(),
2942
+ )
2943
+ ),
2944
+ attr="get_semstr_type",
2945
+ ctx=ast3.Load(),
2946
+ )
2947
+ ),
2948
+ args=[
2949
+ self.sync(
2950
+ ast3.Name(
2951
+ id="__file__", ctx=ast3.Load()
2952
+ )
2953
+ ),
2954
+ scope,
2955
+ self.sync(
2956
+ ast3.Constant(
2957
+ value=(
2958
+ kw_pair.key.value
2959
+ if isinstance(
2960
+ kw_pair.key, ast.Name
2961
+ )
2962
+ else None
2963
+ )
2964
+ )
2965
+ ),
2966
+ self.sync(ast3.Constant(value=False)),
2967
+ ],
2968
+ keywords=[],
2969
+ )
2970
+ ),
2971
+ self.sync(
2972
+ ast3.Constant(
2973
+ value=(
2974
+ kw_pair.key.value
2975
+ if isinstance(kw_pair.key, ast.Name)
2976
+ else None
2977
+ )
2978
+ )
2979
+ ),
2980
+ kw_pair.value.gen.py_ast[0],
2981
+ ],
2982
+ ctx=ast3.Load(),
2983
+ )
2984
+ )
2985
+ for kw_pair in node.params.items
2986
+ if isinstance(kw_pair, ast.KWPair)
2987
+ ]
2988
+ self.cout += 1
2989
+ else:
2990
+ inputs = []
2991
+
2992
+ node.gen.py_ast = [
2993
+ self.sync(
2994
+ ast3.Call(
2995
+ func=self.sync(ast3.Name(id="eval", ctx=ast3.Load())),
2996
+ args=[
2997
+ self.by_llm_call(
2998
+ model,
2999
+ model_params,
3000
+ scope,
3001
+ inputs,
3002
+ outputs,
3003
+ action,
3004
+ include_info,
3005
+ exclude_info,
3006
+ ),
3007
+ ],
3008
+ keywords=[],
3009
+ )
3010
+ )
3011
+ ]
3012
+ else:
3013
+ node.gen.py_ast = [
3014
+ self.sync(ast3.Call(func=func, args=args, keywords=keywords))
3015
+ ]
2856
3016
 
2857
3017
  def exit_index_slice(self, node: ast.IndexSlice) -> None:
2858
3018
  """Sub objects.