langgraph-api 0.2.0__py3-none-any.whl → 0.2.2__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 langgraph-api might be problematic. Click here for more details.

langgraph_api/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.2.0"
1
+ __version__ = "0.2.2"
langgraph_api/api/mcp.py CHANGED
@@ -91,6 +91,13 @@ ERROR_CODE_INVALID_PARAMS = -32602
91
91
  ERROR_CODE_METHOD_NOT_FOUND = -32601
92
92
 
93
93
 
94
+ def _get_version() -> str:
95
+ """Get langgraph-api version."""
96
+ from langgraph_api import __version__
97
+
98
+ return __version__
99
+
100
+
94
101
  async def handle_mcp_endpoint(request: ApiRequest) -> Response:
95
102
  """MCP endpoint handler the implements the Streamable HTTP protocol.
96
103
 
@@ -183,10 +190,11 @@ async def handle_post_request(request: ApiRequest) -> Response:
183
190
  "Invalid JSON-RPC message. Missing or invalid jsonrpc version.", 400
184
191
  )
185
192
 
186
- if id_ and method:
193
+ # Careful ID checks as the integer 0 is a valid ID
194
+ if id_ is not None and method:
187
195
  # JSON-RPC request
188
196
  return await handle_jsonrpc_request(request, cast(JsonRpcRequest, message))
189
- elif id_:
197
+ elif id_ is not None:
190
198
  # JSON-RPC response
191
199
  return handle_jsonrpc_response(cast(JsonRpcResponse, message))
192
200
  elif method:
@@ -292,14 +300,18 @@ def handle_initialize_request(message: JsonRpcRequest) -> dict[str, Any]:
292
300
  """
293
301
  return {
294
302
  "result": {
295
- # We do not return a session ID right now.
303
+ # Official type-script SDK client only works with
304
+ # protocol version 2024-11-05 currently.
305
+ # The protocol is versioning the messages schema and not the transport.
306
+ # https://modelcontextprotocol.io/specification/2025-03-26/basic/lifecycle#lifecycle-phases
307
+ "protocolVersion": "2024-11-05",
296
308
  "capabilities": {
297
309
  "tools": {
298
- # We do not support subscriptions currently
299
310
  "listChanged": False,
300
- },
311
+ }
301
312
  },
302
- },
313
+ "serverInfo": {"name": "LangGraph", "version": _get_version()},
314
+ }
303
315
  }
304
316
 
305
317
 
@@ -380,7 +392,15 @@ async def handle_tools_list(
380
392
  "description": "",
381
393
  },
382
394
  )
383
- return {"result": {"tools": tools, "nextCursor": next_cursor}}
395
+
396
+ result = {"tools": tools}
397
+
398
+ if next_cursor is not None:
399
+ result["nextCursor"] = next_cursor
400
+
401
+ return {
402
+ "result": result,
403
+ }
384
404
 
385
405
 
386
406
  async def handle_tools_call(
@@ -454,7 +474,7 @@ async def handle_tools_call(
454
474
  "result": {
455
475
  "isError": True,
456
476
  "content": [
457
- {"type": "text", "value": value["__error__"]["error"]},
477
+ {"type": "text", "text": value["__error__"]["error"]},
458
478
  ],
459
479
  }
460
480
  }
@@ -463,7 +483,7 @@ async def handle_tools_call(
463
483
  return {
464
484
  "result": {
465
485
  "content": [
466
- {"type": "text", "value": repr(value)},
486
+ {"type": "text", "text": repr(value)},
467
487
  ]
468
488
  }
469
489
  }
@@ -1,3 +1,3 @@
1
1
  {
2
2
  "semi": true
3
- }
3
+ }
@@ -23,7 +23,7 @@ export type CompiledGraphFactory<T extends string> = (config: {
23
23
 
24
24
  export async function resolveGraph(
25
25
  spec: string,
26
- options?: { onlyFilePresence?: false }
26
+ options?: { onlyFilePresence?: false },
27
27
  ): Promise<{
28
28
  sourceFile: string;
29
29
  exportSymbol: string;
@@ -32,12 +32,12 @@ export async function resolveGraph(
32
32
 
33
33
  export async function resolveGraph(
34
34
  spec: string,
35
- options: { onlyFilePresence: true }
35
+ options: { onlyFilePresence: true },
36
36
  ): Promise<{ sourceFile: string; exportSymbol: string; resolved: undefined }>;
37
37
 
38
38
  export async function resolveGraph(
39
39
  spec: string,
40
- options?: { onlyFilePresence?: boolean }
40
+ options?: { onlyFilePresence?: boolean },
41
41
  ) {
42
42
  const [userFile, exportSymbol] = spec.split(":", 2);
43
43
 
@@ -64,7 +64,7 @@ export async function resolveGraph(
64
64
  };
65
65
 
66
66
  const graph: GraphUnknown = await import(sourceFile).then(
67
- (module) => module[exportSymbol || "default"]
67
+ (module) => module[exportSymbol || "default"],
68
68
  );
69
69
 
70
70
  // obtain the graph, and if not compiled, compile it
@@ -92,11 +92,11 @@ export async function resolveGraph(
92
92
 
93
93
  export async function runGraphSchemaWorker(
94
94
  spec: GraphSpec,
95
- options?: { timeoutMs?: number }
95
+ options?: { timeoutMs?: number },
96
96
  ) {
97
97
  return await new Promise<Record<string, GraphSchema>>((resolve, reject) => {
98
98
  const worker = new Worker(
99
- new URL("./parser/parser.worker.mjs", import.meta.url).pathname
99
+ new URL("./parser/parser.worker.mjs", import.meta.url).pathname,
100
100
  );
101
101
 
102
102
  // Set a timeout to reject if the worker takes too long
@@ -6,7 +6,7 @@ parentPort?.on("message", async (payload) => {
6
6
  const result = SubgraphExtractor.extractSchemas(
7
7
  payload.sourceFile,
8
8
  payload.exportSymbol,
9
- { strict: false }
9
+ { strict: false },
10
10
  );
11
11
  parentPort?.postMessage(result);
12
12
  });
@@ -240,7 +240,7 @@ function resolveRequiredFile(
240
240
  symbol: ts.Symbol,
241
241
  key: string,
242
242
  fileName: string,
243
- objectName: string
243
+ objectName: string,
244
244
  ): any {
245
245
  const sourceFile = getSourceFile(symbol);
246
246
  const requiredFilePath = /^[.\/]+/.test(fileName)
@@ -404,7 +404,7 @@ function getCanonicalDeclaration(sym: ts.Symbol): ts.Declaration {
404
404
 
405
405
  const declarationCount = sym.declarations?.length ?? 0;
406
406
  throw new Error(
407
- `Symbol "${sym.name}" has no valueDeclaration and ${declarationCount} declarations.`
407
+ `Symbol "${sym.name}" has no valueDeclaration and ${declarationCount} declarations.`,
408
408
  );
409
409
  }
410
410
 
@@ -418,7 +418,7 @@ function getSourceFile(sym: ts.Symbol): ts.SourceFile {
418
418
  while (currentDecl.kind !== ts.SyntaxKind.SourceFile) {
419
419
  if (currentDecl.parent === undefined) {
420
420
  throw new Error(
421
- `Unable to locate source file for declaration "${sym.name}".`
421
+ `Unable to locate source file for declaration "${sym.name}".`,
422
422
  );
423
423
  }
424
424
  currentDecl = currentDecl.parent;
@@ -561,7 +561,7 @@ class JsonSchemaGenerator {
561
561
  userSymbols: { [name: string]: ts.Symbol },
562
562
  inheritingTypes: { [baseName: string]: string[] },
563
563
  tc: ts.TypeChecker,
564
- private args = getDefaultArgs()
564
+ private args = getDefaultArgs(),
565
565
  ) {
566
566
  this.symbols = symbols;
567
567
  this.allSymbols = allSymbols;
@@ -570,7 +570,7 @@ class JsonSchemaGenerator {
570
570
  this.tc = tc;
571
571
  this.userValidationKeywords = args.validationKeywords.reduce(
572
572
  (acc, word) => ({ ...acc, [word]: true }),
573
- {}
573
+ {},
574
574
  );
575
575
  this.constAsEnum = args.constAsEnum;
576
576
  }
@@ -606,7 +606,7 @@ class JsonSchemaGenerator {
606
606
  private parseCommentsIntoDefinition(
607
607
  symbol: ts.Symbol,
608
608
  definition: Definition,
609
- otherAnnotations: Record<string, true>
609
+ otherAnnotations: Record<string, true>,
610
610
  ): void {
611
611
  if (!symbol) {
612
612
  return;
@@ -621,7 +621,7 @@ class JsonSchemaGenerator {
621
621
  .map((comment) => {
622
622
  const newlineNormalizedComment = comment.text.replace(
623
623
  /\r\n/g,
624
- "\n"
624
+ "\n",
625
625
  );
626
626
 
627
627
  // If a comment contains a "{@link XYZ}" inline tag that could not be
@@ -657,7 +657,7 @@ class JsonSchemaGenerator {
657
657
  }
658
658
  } else if (name === "TJS" && text.startsWith("-")) {
659
659
  let match: string[] | RegExpExecArray | null = new RegExp(
660
- REGEX_TJS_JSDOC
660
+ REGEX_TJS_JSDOC,
661
661
  ).exec(originalText);
662
662
  if (match) {
663
663
  name = match[1];
@@ -673,7 +673,7 @@ class JsonSchemaGenerator {
673
673
  // to process the "." and beyond from the value
674
674
  if (subDefinitions[name]) {
675
675
  const match: string[] | RegExpExecArray | null = new RegExp(
676
- REGEX_GROUP_JSDOC
676
+ REGEX_GROUP_JSDOC,
677
677
  ).exec(text);
678
678
  if (match) {
679
679
  const k = match[1];
@@ -716,7 +716,7 @@ class JsonSchemaGenerator {
716
716
  reffedType: ts.Symbol,
717
717
  definition: Definition,
718
718
  defaultNumberType = this.args.defaultNumberType,
719
- ignoreUndefined = false
719
+ ignoreUndefined = false,
720
720
  ): Definition {
721
721
  const tupleType = resolveTupleType(propertyType);
722
722
 
@@ -725,7 +725,7 @@ class JsonSchemaGenerator {
725
725
  const elemTypes: ts.NodeArray<ts.TypeNode> = (propertyType as any)
726
726
  .typeArguments;
727
727
  const fixedTypes = elemTypes.map((elType) =>
728
- this.getTypeDefinition(elType as any)
728
+ this.getTypeDefinition(elType as any),
729
729
  );
730
730
  definition.type = "array";
731
731
  if (fixedTypes.length > 0) {
@@ -743,12 +743,12 @@ class JsonSchemaGenerator {
743
743
  const propertyTypeString = this.tc.typeToString(
744
744
  propertyType,
745
745
  undefined,
746
- ts.TypeFormatFlags.UseFullyQualifiedType
746
+ ts.TypeFormatFlags.UseFullyQualifiedType,
747
747
  );
748
748
  const flags = propertyType.flags;
749
749
  const arrayType = this.tc.getIndexTypeOfType(
750
750
  propertyType,
751
- ts.IndexKind.Number
751
+ ts.IndexKind.Number,
752
752
  );
753
753
 
754
754
  if (flags & ts.TypeFlags.String) {
@@ -826,7 +826,7 @@ class JsonSchemaGenerator {
826
826
  };
827
827
  if (
828
828
  !!Array.from((propertyType as any).members as any[])?.find(
829
- (member: [string]) => member[0] !== "__index"
829
+ (member: [string]) => member[0] !== "__index",
830
830
  )
831
831
  ) {
832
832
  this.getClassDefinition(propertyType, definition);
@@ -879,7 +879,7 @@ class JsonSchemaGenerator {
879
879
  } else {
880
880
  // Report that type could not be processed
881
881
  const error = new TypeError(
882
- "Unsupported type: " + propertyTypeString
882
+ "Unsupported type: " + propertyTypeString,
883
883
  );
884
884
  (error as any).type = propertyType;
885
885
  throw error;
@@ -908,7 +908,7 @@ class JsonSchemaGenerator {
908
908
 
909
909
  private getDefinitionForProperty(
910
910
  prop: ts.Symbol,
911
- node: ts.Node
911
+ node: ts.Node,
912
912
  ): Definition | null {
913
913
  if (prop.flags & ts.SymbolFlags.Method) {
914
914
  return null;
@@ -923,7 +923,7 @@ class JsonSchemaGenerator {
923
923
  undefined,
924
924
  undefined,
925
925
  prop,
926
- reffedType
926
+ reffedType,
927
927
  );
928
928
 
929
929
  if (this.args.titles) {
@@ -967,12 +967,12 @@ class JsonSchemaGenerator {
967
967
  definition.default = val;
968
968
  } else if (val) {
969
969
  console.warn(
970
- "unknown initializer for property " + propertyName + ": " + val
970
+ "unknown initializer for property " + propertyName + ": " + val,
971
971
  );
972
972
  }
973
973
  } catch (e) {
974
974
  console.warn(
975
- "exception evaluating initializer for property " + propertyName
975
+ "exception evaluating initializer for property " + propertyName,
976
976
  );
977
977
  }
978
978
  }
@@ -983,13 +983,13 @@ class JsonSchemaGenerator {
983
983
 
984
984
  private getEnumDefinition(
985
985
  clazzType: ts.Type,
986
- definition: Definition
986
+ definition: Definition,
987
987
  ): Definition {
988
988
  const node = clazzType.getSymbol()!.getDeclarations()![0];
989
989
  const fullName = this.tc.typeToString(
990
990
  clazzType,
991
991
  undefined,
992
- ts.TypeFormatFlags.UseFullyQualifiedType
992
+ ts.TypeFormatFlags.UseFullyQualifiedType,
993
993
  );
994
994
  const members: ts.NodeArray<ts.EnumMember> =
995
995
  node.kind === ts.SyntaxKind.EnumDeclaration
@@ -1034,7 +1034,7 @@ class JsonSchemaGenerator {
1034
1034
  "initializer is expression for enum: " +
1035
1035
  fullName +
1036
1036
  "." +
1037
- caseLabel
1037
+ caseLabel,
1038
1038
  );
1039
1039
  }
1040
1040
  } else if (
@@ -1068,7 +1068,7 @@ class JsonSchemaGenerator {
1068
1068
  private getUnionDefinition(
1069
1069
  unionType: ts.UnionType,
1070
1070
  unionModifier: keyof Definition,
1071
- definition: Definition
1071
+ definition: Definition,
1072
1072
  ): Definition {
1073
1073
  const enumValues: PrimitiveType[] = [];
1074
1074
  const simpleTypes: JSONSchema7TypeName[] = [];
@@ -1100,7 +1100,7 @@ class JsonSchemaGenerator {
1100
1100
  symbol,
1101
1101
  undefined,
1102
1102
  undefined,
1103
- true
1103
+ true,
1104
1104
  );
1105
1105
  if (def.type === ("undefined" as any)) {
1106
1106
  continue;
@@ -1184,7 +1184,7 @@ class JsonSchemaGenerator {
1184
1184
 
1185
1185
  private getIntersectionDefinition(
1186
1186
  intersectionType: ts.IntersectionType,
1187
- definition: Definition
1187
+ definition: Definition,
1188
1188
  ): Definition {
1189
1189
  const simpleTypes: JSONSchema7TypeName[] = [];
1190
1190
  const schemas: Definition[] = [];
@@ -1230,7 +1230,7 @@ class JsonSchemaGenerator {
1230
1230
 
1231
1231
  private getClassDefinition(
1232
1232
  clazzType: ts.Type,
1233
- definition: Definition
1233
+ definition: Definition,
1234
1234
  ): Definition {
1235
1235
  const node = clazzType.getSymbol()!.getDeclarations()![0];
1236
1236
 
@@ -1277,7 +1277,7 @@ class JsonSchemaGenerator {
1277
1277
  const fullName = this.tc.typeToString(
1278
1278
  clazzType,
1279
1279
  undefined,
1280
- ts.TypeFormatFlags.UseFullyQualifiedType
1280
+ ts.TypeFormatFlags.UseFullyQualifiedType,
1281
1281
  );
1282
1282
 
1283
1283
  const modifierFlags = ts.getCombinedModifierFlags(node);
@@ -1297,7 +1297,7 @@ class JsonSchemaGenerator {
1297
1297
  clazz.members == null
1298
1298
  ? []
1299
1299
  : clazz.members.filter(
1300
- (x) => x.kind === ts.SyntaxKind.IndexSignature
1300
+ (x) => x.kind === ts.SyntaxKind.IndexSignature,
1301
1301
  );
1302
1302
  if (indexSignatures.length === 1) {
1303
1303
  // for case "array-types"
@@ -1305,21 +1305,21 @@ class JsonSchemaGenerator {
1305
1305
  indexSignatures[0] as ts.IndexSignatureDeclaration;
1306
1306
  if (indexSignature.parameters.length !== 1) {
1307
1307
  throw new Error(
1308
- "Not supported: IndexSignatureDeclaration parameters.length != 1"
1308
+ "Not supported: IndexSignatureDeclaration parameters.length != 1",
1309
1309
  );
1310
1310
  }
1311
1311
  const indexSymbol: ts.Symbol = (indexSignature.parameters[0] as any)
1312
1312
  .symbol;
1313
1313
  const indexType = this.tc.getTypeOfSymbolAtLocation(
1314
1314
  indexSymbol,
1315
- node
1315
+ node,
1316
1316
  );
1317
1317
  const isIndexedObject =
1318
1318
  indexType.flags === ts.TypeFlags.String ||
1319
1319
  indexType.flags === ts.TypeFlags.Number;
1320
1320
  if (indexType.flags !== ts.TypeFlags.Number && !isIndexedObject) {
1321
1321
  throw new Error(
1322
- "Not supported: IndexSignatureDeclaration with index symbol other than a number or a string"
1322
+ "Not supported: IndexSignatureDeclaration with index symbol other than a number or a string",
1323
1323
  );
1324
1324
  }
1325
1325
 
@@ -1327,7 +1327,7 @@ class JsonSchemaGenerator {
1327
1327
  let def: Definition | undefined;
1328
1328
  if (typ.flags & ts.TypeFlags.IndexedAccess) {
1329
1329
  const targetName = ts.escapeLeadingUnderscores(
1330
- (clazzType as any).mapper?.target?.value
1330
+ (clazzType as any).mapper?.target?.value,
1331
1331
  );
1332
1332
  const indexedAccessType = typ as ts.IndexedAccessType;
1333
1333
  const symbols: Map<ts.__String, ts.Symbol> = (
@@ -1339,7 +1339,7 @@ class JsonSchemaGenerator {
1339
1339
  const targetNode = targetSymbol.getDeclarations()![0];
1340
1340
  const targetDef = this.getDefinitionForProperty(
1341
1341
  targetSymbol,
1342
- targetNode
1342
+ targetNode,
1343
1343
  );
1344
1344
  if (targetDef) {
1345
1345
  def = targetDef;
@@ -1372,7 +1372,7 @@ class JsonSchemaGenerator {
1372
1372
  }
1373
1373
  return all;
1374
1374
  },
1375
- {}
1375
+ {},
1376
1376
  );
1377
1377
 
1378
1378
  if (definition.type === undefined) {
@@ -1403,7 +1403,7 @@ class JsonSchemaGenerator {
1403
1403
  order.push(prop.getName());
1404
1404
  return order;
1405
1405
  },
1406
- []
1406
+ [],
1407
1407
  );
1408
1408
 
1409
1409
  definition.propertyOrder = propertyOrder;
@@ -1427,7 +1427,7 @@ class JsonSchemaGenerator {
1427
1427
  }
1428
1428
  return required;
1429
1429
  },
1430
- []
1430
+ [],
1431
1431
  );
1432
1432
 
1433
1433
  if (requiredProps.length > 0) {
@@ -1454,9 +1454,9 @@ class JsonSchemaGenerator {
1454
1454
  typ,
1455
1455
  undefined,
1456
1456
  ts.TypeFormatFlags.NoTruncation |
1457
- ts.TypeFormatFlags.UseFullyQualifiedType
1457
+ ts.TypeFormatFlags.UseFullyQualifiedType,
1458
1458
  )
1459
- .replace(REGEX_FILE_NAME_OR_SPACE, "")
1459
+ .replace(REGEX_FILE_NAME_OR_SPACE, ""),
1460
1460
  );
1461
1461
  }
1462
1462
 
@@ -1489,7 +1489,7 @@ class JsonSchemaGenerator {
1489
1489
  reffedType?: ts.Symbol,
1490
1490
  pairedSymbol?: ts.Symbol,
1491
1491
  forceNotRef: boolean = false,
1492
- ignoreUndefined = false
1492
+ ignoreUndefined = false,
1493
1493
  ): Definition {
1494
1494
  const definition: Definition = {}; // real definition
1495
1495
 
@@ -1574,7 +1574,7 @@ class JsonSchemaGenerator {
1574
1574
  .getFullyQualifiedName(
1575
1575
  reffedType!.getFlags() & ts.SymbolFlags.Alias
1576
1576
  ? this.tc.getAliasedSymbol(reffedType!)
1577
- : reffedType!
1577
+ : reffedType!,
1578
1578
  )
1579
1579
  .replace(REGEX_FILE_NAME_OR_SPACE, "");
1580
1580
  if (this.args.uniqueNames && reffedType) {
@@ -1582,7 +1582,7 @@ class JsonSchemaGenerator {
1582
1582
  const relativePath = path.relative(process.cwd(), sourceFile.fileName);
1583
1583
  fullTypeName = `${typeName}.${generateHashOfNode(
1584
1584
  getCanonicalDeclaration(reffedType!),
1585
- relativePath
1585
+ relativePath,
1586
1586
  )}`;
1587
1587
  } else {
1588
1588
  fullTypeName = this.makeTypeNameUnique(typ, typeName);
@@ -1595,7 +1595,7 @@ class JsonSchemaGenerator {
1595
1595
  const relativePath = path.relative(process.cwd(), sourceFile.fileName);
1596
1596
  fullTypeName = `${this.getTypeName(typ)}.${generateHashOfNode(
1597
1597
  getCanonicalDeclaration(sym),
1598
- relativePath
1598
+ relativePath,
1599
1599
  )}`;
1600
1600
  } else if (
1601
1601
  reffedType &&
@@ -1631,20 +1631,20 @@ class JsonSchemaGenerator {
1631
1631
  this.parseCommentsIntoDefinition(
1632
1632
  typ.aliasSymbol!,
1633
1633
  definition,
1634
- otherAnnotations
1634
+ otherAnnotations,
1635
1635
  );
1636
1636
  if (prop) {
1637
1637
  this.parseCommentsIntoDefinition(
1638
1638
  prop,
1639
1639
  returnedDefinition,
1640
- otherAnnotations
1640
+ otherAnnotations,
1641
1641
  );
1642
1642
  }
1643
1643
  if (pairedSymbol && symbol && this.isFromDefaultLib(symbol)) {
1644
1644
  this.parseCommentsIntoDefinition(
1645
1645
  pairedSymbol,
1646
1646
  definition,
1647
- otherAnnotations
1647
+ otherAnnotations,
1648
1648
  );
1649
1649
  }
1650
1650
 
@@ -1669,7 +1669,7 @@ class JsonSchemaGenerator {
1669
1669
  true,
1670
1670
  undefined,
1671
1671
  symbol,
1672
- symbol
1672
+ symbol,
1673
1673
  );
1674
1674
  } else {
1675
1675
  reffedDefinition = definition;
@@ -1693,7 +1693,7 @@ class JsonSchemaGenerator {
1693
1693
  this.getUnionDefinition(
1694
1694
  typ as ts.UnionType,
1695
1695
  unionModifier,
1696
- definition
1696
+ definition,
1697
1697
  );
1698
1698
  } else if (typ.flags & ts.TypeFlags.Intersection) {
1699
1699
  if (this.args.noExtraProps) {
@@ -1711,7 +1711,7 @@ class JsonSchemaGenerator {
1711
1711
  undefined,
1712
1712
  undefined,
1713
1713
  undefined,
1714
- true
1714
+ true,
1715
1715
  );
1716
1716
  definition.type = other.type; // should always be object
1717
1717
  definition.properties = {
@@ -1722,19 +1722,19 @@ class JsonSchemaGenerator {
1722
1722
  if (Object.keys(other.default || {}).length > 0) {
1723
1723
  definition.default = extend(
1724
1724
  definition.default || {},
1725
- other.default
1725
+ other.default,
1726
1726
  );
1727
1727
  }
1728
1728
  if (other.required) {
1729
1729
  definition.required = unique(
1730
- (definition.required || []).concat(other.required)
1730
+ (definition.required || []).concat(other.required),
1731
1731
  ).sort();
1732
1732
  }
1733
1733
  }
1734
1734
  } else {
1735
1735
  this.getIntersectionDefinition(
1736
1736
  typ as ts.IntersectionType,
1737
- definition
1737
+ definition,
1738
1738
  );
1739
1739
  }
1740
1740
  } else if (isRawType) {
@@ -1746,7 +1746,7 @@ class JsonSchemaGenerator {
1746
1746
  reffedType!,
1747
1747
  definition,
1748
1748
  undefined,
1749
- ignoreUndefined
1749
+ ignoreUndefined,
1750
1750
  );
1751
1751
  } else if (
1752
1752
  node &&
@@ -1806,7 +1806,7 @@ class JsonSchemaGenerator {
1806
1806
  public getSchemaForSymbol(
1807
1807
  symbolName: string,
1808
1808
  includeReffedDefinitions: boolean = true,
1809
- includeAllOverrides: boolean = false
1809
+ includeAllOverrides: boolean = false,
1810
1810
  ): Definition {
1811
1811
  const overrideDefinition = this.schemaOverrides.get(symbolName);
1812
1812
  if (!this.allSymbols[symbolName] && !overrideDefinition) {
@@ -1827,7 +1827,7 @@ class JsonSchemaGenerator {
1827
1827
  undefined,
1828
1828
  undefined,
1829
1829
  undefined,
1830
- this.userSymbols[symbolName] || undefined
1830
+ this.userSymbols[symbolName] || undefined,
1831
1831
  );
1832
1832
  }
1833
1833
 
@@ -1849,7 +1849,7 @@ class JsonSchemaGenerator {
1849
1849
  public getSchemaForSymbols(
1850
1850
  symbolNames: string[],
1851
1851
  includeReffedDefinitions: boolean = true,
1852
- includeAllOverrides: boolean = false
1852
+ includeAllOverrides: boolean = false,
1853
1853
  ): Definition {
1854
1854
  const root: {
1855
1855
  $id?: string;
@@ -1875,7 +1875,7 @@ class JsonSchemaGenerator {
1875
1875
  undefined,
1876
1876
  undefined,
1877
1877
  undefined,
1878
- this.userSymbols[symbolName]
1878
+ this.userSymbols[symbolName],
1879
1879
  );
1880
1880
  }
1881
1881
  if (
@@ -1902,7 +1902,7 @@ class JsonSchemaGenerator {
1902
1902
 
1903
1903
  public getMainFileSymbols(
1904
1904
  program: ts.Program,
1905
- onlyIncludeFiles?: string[]
1905
+ onlyIncludeFiles?: string[],
1906
1906
  ): string[] {
1907
1907
  function includeFile(file: ts.SourceFile): boolean {
1908
1908
  if (onlyIncludeFiles === undefined) {
@@ -1940,7 +1940,7 @@ function generateHashOfNode(node: ts.Node, relativePath: string): string {
1940
1940
 
1941
1941
  export function buildGenerator(
1942
1942
  program: ts.Program,
1943
- args: PartialArgs = {}
1943
+ args: PartialArgs = {},
1944
1944
  ): JsonSchemaGenerator | null {
1945
1945
  // Use defaults unless otherwise specified
1946
1946
  const settings = getDefaultArgs();
@@ -1990,7 +1990,7 @@ export function buildGenerator(
1990
1990
  var baseName = tc.typeToString(
1991
1991
  baseType,
1992
1992
  undefined,
1993
- ts.TypeFormatFlags.UseFullyQualifiedType
1993
+ ts.TypeFormatFlags.UseFullyQualifiedType,
1994
1994
  );
1995
1995
  if (!inheritingTypes[baseName]) {
1996
1996
  inheritingTypes[baseName] = [];
@@ -2011,6 +2011,6 @@ export function buildGenerator(
2011
2011
  userSymbols,
2012
2012
  inheritingTypes,
2013
2013
  typeChecker,
2014
- settings
2014
+ settings,
2015
2015
  );
2016
2016
  }
@@ -16,7 +16,7 @@ export const serialiseAsDict = (obj: unknown) => {
16
16
 
17
17
  return value;
18
18
  },
19
- 2
19
+ 2,
20
20
  );
21
21
  };
22
22
 
@@ -6,13 +6,13 @@ import { SignJWT } from "jose";
6
6
 
7
7
  const sql = postgres(
8
8
  process.env.POSTGRES_URI ??
9
- "postgres://postgres:postgres@127.0.0.1:5433/postgres?sslmode=disable"
9
+ "postgres://postgres:postgres@127.0.0.1:5433/postgres?sslmode=disable",
10
10
  );
11
11
 
12
12
  const config = { configurable: { user_id: "123" } };
13
13
 
14
14
  const SECRET_KEY = new TextEncoder().encode(
15
- "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
15
+ "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7",
16
16
  );
17
17
  const ALGORITHM = "HS256";
18
18
 
@@ -37,19 +37,19 @@ beforeAll(async () => {
37
37
  it("unauthenticated user", async () => {
38
38
  const client = await createJwtClient("wfh", ["me"]);
39
39
  await expect(client.assistants.create({ graphId: "agent" })).rejects.toThrow(
40
- "HTTP 401"
40
+ "HTTP 401",
41
41
  );
42
42
  });
43
43
 
44
44
  it("create assistant with forbidden scopes", async () => {
45
45
  let user = await createJwtClient("johndoe");
46
46
  await expect(user.assistants.create({ graphId: "agent" })).rejects.toThrow(
47
- "HTTP 403"
47
+ "HTTP 403",
48
48
  );
49
49
 
50
50
  user = await createJwtClient("johndoe", ["foo"]);
51
51
  await expect(user.assistants.create({ graphId: "agent" })).rejects.toThrow(
52
- "HTTP 403"
52
+ "HTTP 403",
53
53
  );
54
54
 
55
55
  user = await createJwtClient("johndoe", ["assistants:write"]);
@@ -75,7 +75,7 @@ it("get thread history from unauthorized user", async () => {
75
75
 
76
76
  const user2 = await createJwtClient("alice", ["me"]);
77
77
  await expect(
78
- user2.runs.wait(thread.thread_id, "agent", { input, config })
78
+ user2.runs.wait(thread.thread_id, "agent", { input, config }),
79
79
  ).rejects.toThrow("HTTP 404");
80
80
  });
81
81
 
@@ -89,7 +89,7 @@ it("add run to unauthorized thread", async () => {
89
89
 
90
90
  const user2 = await createJwtClient("alice", ["me"]);
91
91
  await expect(
92
- user2.runs.wait(thread.thread_id, "agent", { input, config })
92
+ user2.runs.wait(thread.thread_id, "agent", { input, config }),
93
93
  ).rejects.toThrow("HTTP 404");
94
94
  });
95
95
 
@@ -103,12 +103,12 @@ it("asssistant access control", async () => {
103
103
  await expect(
104
104
  otherUser.assistants.update(assistant.assistant_id, {
105
105
  metadata: { foo: "bar" },
106
- })
106
+ }),
107
107
  ).rejects.toThrow("HTTP 404");
108
108
 
109
109
  // Other user can't delete the assistant
110
110
  await expect(
111
- otherUser.assistants.delete(assistant.assistant_id)
111
+ otherUser.assistants.delete(assistant.assistant_id),
112
112
  ).rejects.toThrow("HTTP 404");
113
113
  });
114
114
 
@@ -120,12 +120,12 @@ it("thread operations auth", async () => {
120
120
 
121
121
  // Other user can't update thread
122
122
  await expect(
123
- otherUser.threads.update(thread.thread_id, { metadata: { foo: "bar" } })
123
+ otherUser.threads.update(thread.thread_id, { metadata: { foo: "bar" } }),
124
124
  ).rejects.toThrow("HTTP 404");
125
125
 
126
126
  // Other user can't delete thread
127
127
  await expect(otherUser.threads.delete(thread.thread_id)).rejects.toThrow(
128
- "HTTP 404"
128
+ "HTTP 404",
129
129
  );
130
130
  });
131
131
 
@@ -142,7 +142,7 @@ it("run streaming auth", async () => {
142
142
  });
143
143
 
144
144
  const chunks = await gatherIterator(
145
- otherUser.runs.joinStream(thread.thread_id, run.run_id)
145
+ otherUser.runs.joinStream(thread.thread_id, run.run_id),
146
146
  );
147
147
 
148
148
  expect(chunks).toMatchObject([
@@ -176,17 +176,17 @@ it("store auth", async () => {
176
176
 
177
177
  // Test store access control
178
178
  await expect(userA.store.getItem(["ALL"], "key_one")).rejects.toThrow(
179
- "HTTP 403"
179
+ "HTTP 403",
180
180
  );
181
181
  await expect(
182
- userA.store.putItem(["ALL"], "key_one", { foo: "bar" })
182
+ userA.store.putItem(["ALL"], "key_one", { foo: "bar" }),
183
183
  ).rejects.toThrow("HTTP 403");
184
184
  await expect(userA.store.deleteItem(["ALL"], "key_one")).rejects.toThrow(
185
- "HTTP 403"
185
+ "HTTP 403",
186
186
  );
187
187
  await expect(userA.store.searchItems(["ALL"])).rejects.toThrow("HTTP 403");
188
188
  await expect(userA.store.listNamespaces({ prefix: ["ALL"] })).rejects.toThrow(
189
- "HTTP 403"
189
+ "HTTP 403",
190
190
  );
191
191
 
192
192
  // Test owner can access their own store
@@ -199,7 +199,7 @@ it("store auth", async () => {
199
199
  });
200
200
 
201
201
  expect(
202
- await userA.store.listNamespaces({ prefix: ["johndoe"] })
202
+ await userA.store.listNamespaces({ prefix: ["johndoe"] }),
203
203
  ).toMatchObject({ namespaces: [["johndoe"]] });
204
204
 
205
205
  // Test other user can access their own store
@@ -210,11 +210,11 @@ it("store auth", async () => {
210
210
  items: [{ key: "key_one", value: { text: "test user B" } }],
211
211
  });
212
212
  expect(await userB.store.listNamespaces({ prefix: ["alice"] })).toMatchObject(
213
- { namespaces: [["alice"]] }
213
+ { namespaces: [["alice"]] },
214
214
  );
215
215
  });
216
216
 
217
- it("run cancellation", async () => {
217
+ it("run cancellation", { retry: 3 }, async () => {
218
218
  const owner = await createJwtClient("johndoe", ["me"]);
219
219
  const otherUser = await createJwtClient("alice", ["me"]);
220
220
 
@@ -227,7 +227,7 @@ it("run cancellation", async () => {
227
227
 
228
228
  // Other user can't cancel the run
229
229
  await expect(
230
- otherUser.runs.cancel(thread.thread_id, run.run_id)
230
+ otherUser.runs.cancel(thread.thread_id, run.run_id),
231
231
  ).rejects.toThrow("HTTP 404");
232
232
 
233
233
  // Owner can cancel their own run
@@ -246,13 +246,13 @@ it("get assistant ownership", async () => {
246
246
 
247
247
  // Another user cannot get this assistant
248
248
  await expect(
249
- otherUser.assistants.get(assistant.assistant_id)
249
+ otherUser.assistants.get(assistant.assistant_id),
250
250
  ).rejects.toThrow("HTTP 404");
251
251
 
252
252
  // Test invalid assistant IDs
253
253
  const nonexistantUuid = crypto.randomUUID();
254
254
  await expect(owner.assistants.get(nonexistantUuid)).rejects.toThrow(
255
- "HTTP 404"
255
+ "HTTP 404",
256
256
  );
257
257
  });
258
258
 
@@ -270,7 +270,7 @@ it("get assistant graph", async () => {
270
270
 
271
271
  // Another user can't access the graph
272
272
  await expect(
273
- otherUser.assistants.getGraph(assistant.assistant_id)
273
+ otherUser.assistants.getGraph(assistant.assistant_id),
274
274
  ).rejects.toThrow("HTTP 404");
275
275
  });
276
276
 
@@ -301,10 +301,10 @@ it("thread state operations", async () => {
301
301
 
302
302
  // Another user cannot access or modify state
303
303
  await expect(otherUser.threads.getState(thread.thread_id)).rejects.toThrow(
304
- "HTTP 404"
304
+ "HTTP 404",
305
305
  );
306
306
  await expect(
307
- otherUser.threads.updateState(thread.thread_id, { values: { sleep: 432 } })
307
+ otherUser.threads.updateState(thread.thread_id, { values: { sleep: 432 } }),
308
308
  ).rejects.toThrow("HTTP 404");
309
309
  });
310
310
 
@@ -324,7 +324,7 @@ it("run operations", async () => {
324
324
  // Owner can list runs
325
325
  const runs = await owner.runs.list(thread.thread_id);
326
326
  expect(runs).toMatchObject(
327
- expect.arrayContaining([expect.objectContaining({ run_id: run.run_id })])
327
+ expect.arrayContaining([expect.objectContaining({ run_id: run.run_id })]),
328
328
  );
329
329
 
330
330
  // Owner can get specific run
@@ -333,18 +333,18 @@ it("run operations", async () => {
333
333
 
334
334
  // Another user cannot access runs, cancel or delete a run not owned by them
335
335
  await expect(otherUser.runs.list(thread.thread_id)).rejects.toThrow(
336
- "HTTP 404"
336
+ "HTTP 404",
337
337
  );
338
338
  await expect(
339
- otherUser.runs.get(thread.thread_id, run.run_id)
339
+ otherUser.runs.get(thread.thread_id, run.run_id),
340
340
  ).rejects.toThrow("HTTP 404");
341
341
 
342
342
  await expect(
343
- otherUser.runs.cancel(thread.thread_id, run.run_id, true)
343
+ otherUser.runs.cancel(thread.thread_id, run.run_id, true),
344
344
  ).rejects.toThrow("HTTP 404");
345
345
 
346
346
  await expect(
347
- otherUser.runs.delete(thread.thread_id, run.run_id)
347
+ otherUser.runs.delete(thread.thread_id, run.run_id),
348
348
  ).rejects.toThrow("HTTP 404");
349
349
 
350
350
  // Owner can cancel run
@@ -353,7 +353,7 @@ it("run operations", async () => {
353
353
  // Owner can delete run
354
354
  await owner.runs.delete(thread.thread_id, run.run_id);
355
355
  await expect(owner.runs.get(thread.thread_id, run.run_id)).rejects.toThrow(
356
- "HTTP 404"
356
+ "HTTP 404",
357
357
  );
358
358
  });
359
359
 
@@ -367,7 +367,7 @@ it("create run in other user thread", async () => {
367
367
  };
368
368
 
369
369
  await expect(
370
- otherUser.runs.create(thread.thread_id, "agent", { input, config })
370
+ otherUser.runs.create(thread.thread_id, "agent", { input, config }),
371
371
  ).rejects.toThrow("HTTP 404");
372
372
  });
373
373
 
@@ -388,7 +388,7 @@ it("list runs other user thread", async () => {
388
388
 
389
389
  // Other user cannot list runs
390
390
  await expect(otherUser.runs.list(thread.thread_id)).rejects.toThrow(
391
- "HTTP 404"
391
+ "HTTP 404",
392
392
  );
393
393
  });
394
394
 
@@ -404,7 +404,7 @@ it("get run other user thread", async () => {
404
404
 
405
405
  // Other user attempts to get the run
406
406
  await expect(
407
- otherUser.runs.get(thread.thread_id, run.run_id)
407
+ otherUser.runs.get(thread.thread_id, run.run_id),
408
408
  ).rejects.toThrow("HTTP 404");
409
409
  });
410
410
 
@@ -420,7 +420,7 @@ it("join run other user thread", async () => {
420
420
 
421
421
  // Other user tries to join the run
422
422
  await expect(
423
- otherUser.runs.join(thread.thread_id, run.run_id)
423
+ otherUser.runs.join(thread.thread_id, run.run_id),
424
424
  ).rejects.toThrow("HTTP 404");
425
425
  });
426
426
 
@@ -434,7 +434,7 @@ it("wait run other user thread", async () => {
434
434
 
435
435
  // Other user tries to wait on run result
436
436
  await expect(
437
- otherUser.runs.wait(thread.thread_id, "agent", { input, config })
437
+ otherUser.runs.wait(thread.thread_id, "agent", { input, config }),
438
438
  ).rejects.toThrow("HTTP 404");
439
439
  });
440
440
 
@@ -450,7 +450,7 @@ it("stream run other user thread", async () => {
450
450
 
451
451
  // Other user tries to join_stream
452
452
  const chunks = await gatherIterator(
453
- otherUser.runs.joinStream(thread.thread_id, run.run_id)
453
+ otherUser.runs.joinStream(thread.thread_id, run.run_id),
454
454
  );
455
455
  expect(chunks).toHaveLength(1);
456
456
  expect(chunks).toMatchObject([
@@ -470,7 +470,7 @@ it("cancel run other user thread", { retry: 3 }, async () => {
470
470
  });
471
471
 
472
472
  await expect(
473
- otherUser.runs.cancel(thread.thread_id, run.run_id)
473
+ otherUser.runs.cancel(thread.thread_id, run.run_id),
474
474
  ).rejects.toThrow("HTTP 404");
475
475
 
476
476
  await owner.runs.cancel(thread.thread_id, run.run_id);
@@ -488,7 +488,7 @@ it("delete run other user thread", async () => {
488
488
  });
489
489
 
490
490
  await expect(
491
- otherUser.runs.delete(thread.thread_id, run.run_id)
491
+ otherUser.runs.delete(thread.thread_id, run.run_id),
492
492
  ).rejects.toThrow("HTTP 404");
493
493
 
494
494
  await owner.runs.cancel(thread.thread_id, run.run_id);
@@ -503,7 +503,7 @@ it("update thread state other user", async () => {
503
503
 
504
504
  // Other user tries to update state
505
505
  await expect(
506
- otherUser.threads.updateState(thread.thread_id, newState)
506
+ otherUser.threads.updateState(thread.thread_id, newState),
507
507
  ).rejects.toThrow("HTTP 404");
508
508
  });
509
509
 
@@ -528,7 +528,7 @@ it("get checkpoint other user", async () => {
528
528
  }
529
529
 
530
530
  await expect(
531
- otherUser.threads.getState(thread.thread_id, checkpointId)
531
+ otherUser.threads.getState(thread.thread_id, checkpointId),
532
532
  ).rejects.toThrow("HTTP 404");
533
533
  });
534
534
 
@@ -544,10 +544,10 @@ it("assistant version leakage", async () => {
544
544
  expect(result.metadata?.foo).toBe(someId);
545
545
 
546
546
  await expect(
547
- otherUser.assistants.getVersions(assistant.assistant_id)
547
+ otherUser.assistants.getVersions(assistant.assistant_id),
548
548
  ).rejects.toThrow("HTTP 404");
549
549
  await expect(
550
- otherUser.assistants.setLatest(assistant.assistant_id, 1)
550
+ otherUser.assistants.setLatest(assistant.assistant_id, 1),
551
551
  ).rejects.toThrow("HTTP 404");
552
552
  });
553
553
 
@@ -562,7 +562,7 @@ it("assistant set latest", async () => {
562
562
  expect(updated.metadata?.foo).toBe("bar");
563
563
 
564
564
  await expect(
565
- otherUser.assistants.setLatest(assistant.assistant_id, 1)
565
+ otherUser.assistants.setLatest(assistant.assistant_id, 1),
566
566
  ).rejects.toThrow("HTTP 404");
567
567
 
568
568
  const result = await owner.assistants.setLatest(assistant.assistant_id, 1);
@@ -580,18 +580,18 @@ it("assistant search filtering", async () => {
580
580
  // each user should only see their own assistants
581
581
  const results1 = await user1.assistants.search();
582
582
  expect(results1).toContainEqual(
583
- expect.objectContaining({ assistant_id: assistant1.assistant_id })
583
+ expect.objectContaining({ assistant_id: assistant1.assistant_id }),
584
584
  );
585
585
  expect(results1).not.toContainEqual(
586
- expect.objectContaining({ assistant_id: assistant2.assistant_id })
586
+ expect.objectContaining({ assistant_id: assistant2.assistant_id }),
587
587
  );
588
588
 
589
589
  const results2 = await user2.assistants.search();
590
590
  expect(results2).toContainEqual(
591
- expect.objectContaining({ assistant_id: assistant2.assistant_id })
591
+ expect.objectContaining({ assistant_id: assistant2.assistant_id }),
592
592
  );
593
593
  expect(results2).not.toContainEqual(
594
- expect.objectContaining({ assistant_id: assistant1.assistant_id })
594
+ expect.objectContaining({ assistant_id: assistant1.assistant_id }),
595
595
  );
596
596
  });
597
597
 
@@ -603,7 +603,7 @@ it("thread copy authorization", async () => {
603
603
 
604
604
  // Other user can't copy the thread
605
605
  await expect(otherUser.threads.copy(thread.thread_id)).rejects.toThrow(
606
- "HTTP 409"
606
+ "HTTP 409",
607
607
  );
608
608
 
609
609
  // Owner can copy the thread
@@ -623,7 +623,7 @@ it("thread history authorization", async () => {
623
623
  expect(history).toHaveLength(5);
624
624
 
625
625
  await expect(otherUser.threads.getHistory(thread.thread_id)).rejects.toThrow(
626
- "HTTP 404"
626
+ "HTTP 404",
627
627
  );
628
628
  });
629
629
 
@@ -641,7 +641,7 @@ it("test stateless runs", async () => {
641
641
 
642
642
  expect(values).not.toBeNull();
643
643
  const chunks = await gatherIterator(
644
- owner.runs.stream(null, assistant.assistant_id, { input, config })
644
+ owner.runs.stream(null, assistant.assistant_id, { input, config }),
645
645
  );
646
646
 
647
647
  expect(chunks.find((i) => i.event === "error")).not.toBeDefined();
@@ -37,7 +37,7 @@ class StableFakeListChatModel extends FakeListChatModel {
37
37
  async *_streamResponseChunks(
38
38
  _messages: BaseMessage[],
39
39
  options: this["ParsedCallOptions"],
40
- runManager?: CallbackManagerForLLMRun
40
+ runManager?: CallbackManagerForLLMRun,
41
41
  ): AsyncGenerator<ChatGenerationChunk> {
42
42
  const response = this._currentResponse();
43
43
  this._incrementResponse();
@@ -68,7 +68,7 @@ class StableFakeListChatModel extends FakeListChatModel {
68
68
  undefined,
69
69
  undefined,
70
70
  undefined,
71
- { chunk }
71
+ { chunk },
72
72
  );
73
73
  }
74
74
  }
@@ -88,7 +88,7 @@ const getModel = (threadId: string) => {
88
88
 
89
89
  const agentNode = async (
90
90
  state: typeof GraphAnnotationInput.State,
91
- config: LangGraphRunnableConfig
91
+ config: LangGraphRunnableConfig,
92
92
  ) => {
93
93
  if (state.interrupt) interrupt("i want to interrupt");
94
94
 
@@ -120,7 +120,7 @@ const agentNode = async (
120
120
 
121
121
  const toolNode = async (
122
122
  state: typeof GraphAnnotationInput.State,
123
- config: LangGraphRunnableConfig
123
+ config: LangGraphRunnableConfig,
124
124
  ) => {
125
125
  const store = config.store;
126
126
  let sharedStateFromStoreConfig: Record<string, any> | null = null;
@@ -144,7 +144,7 @@ const toolNode = async (
144
144
 
145
145
  const checkSharedStateNode = async (
146
146
  _: typeof GraphAnnotationInput.State,
147
- config: LangGraphRunnableConfig
147
+ config: LangGraphRunnableConfig,
148
148
  ): Promise<Partial<typeof GraphAnnotationInput.State>> => {
149
149
  const store = config.store;
150
150
  const namespace = ["inputtedState", "data"];
@@ -174,7 +174,7 @@ const workflow = new StateGraph(
174
174
  input: GraphAnnotationInput,
175
175
  output: GraphAnnotationOutput,
176
176
  },
177
- Annotation.Root({ model_name: Annotation<string> })
177
+ Annotation.Root({ model_name: Annotation<string> }),
178
178
  )
179
179
  .addNode("agent", agentNode)
180
180
  .addNode("tool", toolNode)
@@ -2,7 +2,7 @@ import { Auth, HTTPException } from "@langchain/langgraph-sdk/auth";
2
2
  import { JWTPayload, jwtVerify } from "jose";
3
3
 
4
4
  const SECRET_KEY = new TextEncoder().encode(
5
- "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
5
+ "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7",
6
6
  );
7
7
  const ALGORITHM = "HS256";
8
8
 
@@ -38,7 +38,7 @@ export const graph = new StateGraph(StateSchema)
38
38
  new Send("task", { value: 3 }),
39
39
  ],
40
40
  }),
41
- { ends: ["task"] }
41
+ { ends: ["task"] },
42
42
  )
43
43
  .addNode("task", (arg: { value: number }) => ({
44
44
  messages: [`task: ${arg.value}`],
@@ -12,7 +12,7 @@ const StateSchema = Annotation.Root({
12
12
  });
13
13
 
14
14
  const longRunning = async (
15
- state: typeof StateSchema.State
15
+ state: typeof StateSchema.State,
16
16
  ): Promise<typeof StateSchema.Update> => {
17
17
  if (state.delay === -1) {
18
18
  while (true) {
@@ -6,7 +6,7 @@ const child = new StateGraph(
6
6
  reducer: (a, b) => a.concat(b),
7
7
  }),
8
8
  child: Annotation<"child_one" | "child_two">,
9
- })
9
+ }),
10
10
  )
11
11
  .addNode("c_one", () => ({ messages: ["Entered c_one node"] }))
12
12
  .addNode("c_two", () => ({ messages: ["Entered c_two node"] }))
@@ -20,7 +20,7 @@ const parent = new StateGraph(
20
20
  reducer: (a, b) => a.concat(b),
21
21
  }),
22
22
  parent: Annotation<"parent_one" | "parent_two">,
23
- })
23
+ }),
24
24
  )
25
25
  .addNode("p_one", () => ({ messages: ["Entered p_one node"] }))
26
26
  .addNode("p_two", child.compile())
@@ -33,7 +33,7 @@ const grandParent = new StateGraph(
33
33
  messages: Annotation<string[]>({
34
34
  reducer: (a, b) => a.concat(b),
35
35
  }),
36
- })
36
+ }),
37
37
  )
38
38
  .addNode("gp_one", () => ({ messages: ["Entered gp_one node"] }))
39
39
  .addNode("gp_two", parent.compile())
@@ -49,7 +49,7 @@ const router = new StateGraph(routerState)
49
49
  if (route === "weather") return "weather_graph";
50
50
  return "normal_llm_node";
51
51
  },
52
- ["weather_graph", "normal_llm_node"]
52
+ ["weather_graph", "normal_llm_node"],
53
53
  )
54
54
  .addEdge("weather_graph", END)
55
55
  .addEdge("normal_llm_node", END);
@@ -1,5 +1,5 @@
1
1
  export async function gatherIterator<T>(
2
- i: AsyncIterable<T> | Promise<AsyncIterable<T>>
2
+ i: AsyncIterable<T> | Promise<AsyncIterable<T>>,
3
3
  ): Promise<Array<T>> {
4
4
  const out: T[] = [];
5
5
  for await (const item of await i) out.push(item);
@@ -8,7 +8,7 @@ export async function gatherIterator<T>(
8
8
 
9
9
  export function findLast<T, S extends T>(
10
10
  lst: Array<T>,
11
- predicate: (item: T) => item is S
11
+ predicate: (item: T) => item is S,
12
12
  ): S | undefined {
13
13
  for (let i = lst.length - 1; i >= 0; i--) {
14
14
  if (predicate(lst[i])) return lst[i] as S;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: langgraph-api
3
- Version: 0.2.0
3
+ Version: 0.2.2
4
4
  Summary:
5
5
  License: Elastic-2.0
6
6
  Author: Nuno Campos
@@ -16,7 +16,7 @@ Requires-Dist: cryptography (>=42.0.0,<45.0)
16
16
  Requires-Dist: httpx (>=0.25.0)
17
17
  Requires-Dist: jsonschema-rs (>=0.20.0,<0.30)
18
18
  Requires-Dist: langchain-core (>=0.2.38) ; python_version < "4.0"
19
- Requires-Dist: langgraph (>=0.2.56) ; python_version < "4.0"
19
+ Requires-Dist: langgraph (>=0.3.27) ; python_version < "4.0"
20
20
  Requires-Dist: langgraph-checkpoint (>=2.0.23) ; python_version < "4.0"
21
21
  Requires-Dist: langgraph-runtime-inmem (>=0.0.7)
22
22
  Requires-Dist: langgraph-sdk (>=0.1.66,<0.2.0) ; python_version < "4.0"
@@ -1,8 +1,8 @@
1
1
  LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
2
- langgraph_api/__init__.py,sha256=Zn1KFblwuFHiDRdRAiRnDBRkbPttWh44jKa5zG2ov0E,22
2
+ langgraph_api/__init__.py,sha256=m6kyaNpwBcP1XYcqrelX2oS3PJuOnElOcRdBa9pEb8c,22
3
3
  langgraph_api/api/__init__.py,sha256=IKKMrC5gCHTzjprbg8jgZDrAJRuqJfSUgEkZAgh3l-M,5771
4
4
  langgraph_api/api/assistants.py,sha256=6oYFRKlvqheJQGbWjFhQOUnnSbvsbrdMYLRJP7WtSRo,14481
5
- langgraph_api/api/mcp.py,sha256=KbR19dtFCpJEiKYj3IfepAuJij8YZVELuVp7JY_yu_o,13754
5
+ langgraph_api/api/mcp.py,sha256=RvRYgANqRzNQzSmgjNkq4RlKTtoEJYil04ot9lsmEtE,14352
6
6
  langgraph_api/api/meta.py,sha256=sTgkhE-DaFWpERG6F7KelZfDsmJAiVc4j5dg50tDkSo,2950
7
7
  langgraph_api/api/openapi.py,sha256=OGwzPpYO4e98iqtgL7UEfzI6jP4zXahJ1R-7VgOSZeg,11046
8
8
  langgraph_api/api/runs.py,sha256=dhHZ3xu7V0anftqzXaOYnhVEryJpVeqzu60MFiUw4u8,18010
@@ -26,7 +26,7 @@ langgraph_api/errors.py,sha256=Bu_i5drgNTyJcLiyrwVE_6-XrSU50BHf9TDpttki9wQ,1690
26
26
  langgraph_api/graph.py,sha256=YyWCPtoI9VDV0knjCMUFoH4r9OFVsAiv5K8FzbziMqs,21488
27
27
  langgraph_api/http.py,sha256=gYbxxjY8aLnsXeJymcJ7G7Nj_yToOGpPYQqmZ1_ggfA,5240
28
28
  langgraph_api/js/.gitignore,sha256=l5yI6G_V6F1600I1IjiUKn87f4uYIrBAYU1MOyBBhg4,59
29
- langgraph_api/js/.prettierrc,sha256=r08GtR4CPFQkArPYy10eMUbrpTvGDVNeoZRvaeZu0Kc,18
29
+ langgraph_api/js/.prettierrc,sha256=0es3ovvyNIqIw81rPQsdt1zCQcOdBqyR_DMbFE4Ifms,19
30
30
  langgraph_api/js/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
31
31
  langgraph_api/js/base.py,sha256=gjY6K8avI03OrI-Hy6a311fQ_EG5r_x8hUYlc7uqxdE,534
32
32
  langgraph_api/js/build.mts,sha256=ceHRr_Io_9otkDOSgHuKbGnOUu4AX2jPj8APTTa9UjM,2741
@@ -37,40 +37,40 @@ langgraph_api/js/global.d.ts,sha256=j4GhgtQSZ5_cHzjSPcHgMJ8tfBThxrH-pUOrrJGteOU,
37
37
  langgraph_api/js/package.json,sha256=5gtQpj0mXh069X5fWJFWp-jt7Sb3RQUPVpe4m8Q0KHE,1289
38
38
  langgraph_api/js/remote.py,sha256=ipAITSDyh-kNau37nfRg-PSB-6Lbtax3UJap8-lLZdw,35729
39
39
  langgraph_api/js/schema.py,sha256=7idnv7URlYUdSNMBXQcw7E4SxaPxCq_Oxwnlml8q5ik,408
40
- langgraph_api/js/src/graph.mts,sha256=QVy2sUcwcG9WkPF6AXy9mh0dvaXccVIZNtv5rkUtUYc,3479
40
+ langgraph_api/js/src/graph.mts,sha256=_xKhdO2WAwsieoezFqTCcx1IDeHeN6GSMv0lyBsakKI,3485
41
41
  langgraph_api/js/src/load.hooks.mjs,sha256=xNVHq75W0Lk6MUKl1pQYrx-wtQ8_neiUyI6SO-k0ecM,2235
42
42
  langgraph_api/js/src/parser/parser.mts,sha256=iW5G-YIVIuwuFsfn_GS3_CZsjpa00SxypICfPf2SN9Q,14156
43
- langgraph_api/js/src/parser/parser.worker.mjs,sha256=2K6D0GlUmkk7LE39I8mryB8VZVE3-N9Cblji-ArPhFo,386
44
- langgraph_api/js/src/parser/schema/types.mts,sha256=SRCYZTWjxyc7528DaapR_DCm3G5bfDSh4vf-JsYpk0w,62633
43
+ langgraph_api/js/src/parser/parser.worker.mjs,sha256=Byo65U2aI3FtZaUwRRq65xBpwornoR6ldak333jxH4c,387
44
+ langgraph_api/js/src/parser/schema/types.mts,sha256=Vx34tLAncRnITwAVe1wABFgM86TpByMLQ5y5pnit4tI,62693
45
45
  langgraph_api/js/src/parser/schema/types.template.mts,sha256=Dbjj_8d-OubqH4QY_OaxSu8ocZ4dVjI94oncL20fqtk,2235
46
46
  langgraph_api/js/src/preload.mjs,sha256=ORV7xwMuZcXWL6jQxNAcCYp8GZVYIvVJbUhmle8jbno,759
47
47
  langgraph_api/js/src/utils/files.mts,sha256=MXC-3gy0pkS82AjPBoUN83jY_qg37WSAPHOA7DwfB4M,141
48
48
  langgraph_api/js/src/utils/importMap.mts,sha256=pX4TGOyUpuuWF82kXcxcv3-8mgusRezOGe6Uklm2O5A,1644
49
49
  langgraph_api/js/src/utils/pythonSchemas.mts,sha256=98IW7Z_VP7L_CHNRMb3_MsiV3BgLE2JsWQY_PQcRR3o,685
50
- langgraph_api/js/src/utils/serde.mts,sha256=OuyyO9btvwWd55rU_H4x91dFEJiaPxL-lL9O6Zgo908,742
50
+ langgraph_api/js/src/utils/serde.mts,sha256=D9o6MwTgwPezC_DEmsWS5NnLPnjPMVWIb1I1D4QPEPo,743
51
51
  langgraph_api/js/sse.py,sha256=lsfp4nyJyA1COmlKG9e2gJnTttf_HGCB5wyH8OZBER8,4105
52
52
  langgraph_api/js/tests/api.test.mts,sha256=qjHkSdgTDiBauhxRD4yNMufD5xfZh9BNZ7nD7hTgyzo,68125
53
- langgraph_api/js/tests/auth.test.mts,sha256=Aink9N0y3VCxp-Q0sLapAmdiUBYGzcwU8_3RXkRYN4c,21614
53
+ langgraph_api/js/tests/auth.test.mts,sha256=mMhKe9ggJw4BgUqzSVwqYY3HLMXXEBZ23iiKK8Yq1mM,21678
54
54
  langgraph_api/js/tests/compose-postgres.auth.yml,sha256=iPfJbCeYZdV6GiRLiDn_f7qgpG4TyyGaQ4lV-ZXr6Qk,1768
55
55
  langgraph_api/js/tests/compose-postgres.yml,sha256=w4B3YRS0QEnTcZH2-MY0DYvR_c5GcER0uDa1Ga_knf8,1960
56
56
  langgraph_api/js/tests/graphs/.gitignore,sha256=26J8MarZNXh7snXD5eTpV3CPFTht5Znv8dtHYCLNfkw,12
57
57
  langgraph_api/js/tests/graphs/agent.css,sha256=QgcOC0W7IBsrg4pSqqpull-WTgtULZfx_lF_5ZxLdag,23
58
- langgraph_api/js/tests/graphs/agent.mts,sha256=E9WMv0alMv0njUEECqEsqoRk9NXJUgXW7SyQJ3GOZ8k,5396
58
+ langgraph_api/js/tests/graphs/agent.mts,sha256=0CizKahPnDg5JB9_zGyZRQc7RCM19SV4FiWxscLAWY0,5402
59
59
  langgraph_api/js/tests/graphs/agent.ui.tsx,sha256=JDFJdpdIS6rglkXTaROSb1Is0j1kt5wN9ML8W4cuht8,175
60
60
  langgraph_api/js/tests/graphs/agent_simple.mts,sha256=EDaQXM5x73HhcHoujezOX5C27uZdGdtfMVBE9o4hleE,2998
61
- langgraph_api/js/tests/graphs/auth.mts,sha256=kF2TZP3n_urWigf0qgejZqTe93-341_Mhqe_qnBO_Io,3195
62
- langgraph_api/js/tests/graphs/command.mts,sha256=YO1_cEs_n9VsH_-IediLnI4Yc8KRlp4qrprUZXpAlwM,1163
63
- langgraph_api/js/tests/graphs/delay.mts,sha256=CFneKxqI4bGGK0lYjSbe80QirowPQlsRSuhDUKfydhk,703
61
+ langgraph_api/js/tests/graphs/auth.mts,sha256=MS7pyla1bHRT5Ll-6-vxqcr6-kjbMorn4wG7LlMiOzg,3196
62
+ langgraph_api/js/tests/graphs/command.mts,sha256=HAliqio19XXSe4nTxKMCCIm7uUc0jPvvs6KUW16Cqhc,1164
63
+ langgraph_api/js/tests/graphs/delay.mts,sha256=LPZSex0AJO_Bcp1qtS6P92VRVN9rBZQQLBSsPUd6gOc,704
64
64
  langgraph_api/js/tests/graphs/dynamic.mts,sha256=Wf_-keF7lkEfp_iyI45nlFGCeU8ARLQ8axc0LXh7TyE,659
65
65
  langgraph_api/js/tests/graphs/error.mts,sha256=l4tk89449dj1BnEF_0ZcfPt0Ikk1gl8L1RaSnRfr3xo,487
66
66
  langgraph_api/js/tests/graphs/http.mts,sha256=64xbMlLA58323zOX68Zh57zIB5Zl8ZCqEWRPNdJ-oJs,2171
67
67
  langgraph_api/js/tests/graphs/langgraph.json,sha256=h6hV1wkNEUIpLBX9JOUKqtIBvbhvzyLEuWtBIHteseg,265
68
- langgraph_api/js/tests/graphs/nested.mts,sha256=4G7jSOSaFVQAza-_ARbK-Iai1biLlF2DIPDZXf7PLIY,1245
68
+ langgraph_api/js/tests/graphs/nested.mts,sha256=e06kFzcX2zEJlb7e5B6kMnuZn6sfvsO7PCcYGkkV-8U,1248
69
69
  langgraph_api/js/tests/graphs/package.json,sha256=8kgqWdZJCwekCqjsSrhbLrAPZ2vEy1DmcC8EQnwJMDU,262
70
- langgraph_api/js/tests/graphs/weather.mts,sha256=A7mLK3xW8h5B-ZyJNAyX2M2fJJwzPJzXs4DYesJwreQ,1655
70
+ langgraph_api/js/tests/graphs/weather.mts,sha256=Gef9dCXxoVgNa4Ba0AcoptodYV85Ed2CGcleUB9BRMk,1656
71
71
  langgraph_api/js/tests/graphs/yarn.lock,sha256=HDLJKx47Y-csPzA5eYUMVHWE8fMKrZgrc4SEkQAYYCE,11201
72
72
  langgraph_api/js/tests/parser.test.mts,sha256=BBKUTveZnf-RI6B9XfTBLqy6tp84ddyu1tN3z041IAs,27900
73
- langgraph_api/js/tests/utils.mts,sha256=q1V9gvT63v95onlfK9W4iv3n9ZJO3h-0RD9TdDYuRyY,439
73
+ langgraph_api/js/tests/utils.mts,sha256=Jk1ZZmllNgSS6FJlSs9VaQxHqCEUzkqB5rRQwTSAOP4,441
74
74
  langgraph_api/js/tsconfig.json,sha256=imCYqVnqFpaBoZPx8k1nO4slHIWBFsSlmCYhO73cpBs,341
75
75
  langgraph_api/js/ui.py,sha256=XNT8iBcyT8XmbIqSQUWd-j_00HsaWB2vRTVabwFBkik,2439
76
76
  langgraph_api/js/yarn.lock,sha256=OEj5JbffHe8opUAki0eH_0XJbVmgasv9zcHhGeI0g0w,84019
@@ -101,8 +101,8 @@ langgraph_license/validation.py,sha256=ZKraAVJArAABKqrmHN-EN18ncoNUmRm500Yt1Sc7t
101
101
  langgraph_runtime/__init__.py,sha256=O4GgSmu33c-Pr8Xzxj_brcK5vkm70iNTcyxEjICFZxA,1075
102
102
  logging.json,sha256=3RNjSADZmDq38eHePMm1CbP6qZ71AmpBtLwCmKU9Zgo,379
103
103
  openapi.json,sha256=BMQQYQaTAvCCIqB5YSjriXRHmX9cVsWPWPNfEBs-_kA,133200
104
- langgraph_api-0.2.0.dist-info/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
105
- langgraph_api-0.2.0.dist-info/METADATA,sha256=Z7qxE4sm4MFNSznyXChTSy7pA0GCfnR1klUrAg7EI7M,4235
106
- langgraph_api-0.2.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
107
- langgraph_api-0.2.0.dist-info/entry_points.txt,sha256=3EYLgj89DfzqJHHYGxPH4A_fEtClvlRbWRUHaXO7hj4,77
108
- langgraph_api-0.2.0.dist-info/RECORD,,
104
+ langgraph_api-0.2.2.dist-info/LICENSE,sha256=ZPwVR73Biwm3sK6vR54djCrhaRiM4cAD2zvOQZV8Xis,3859
105
+ langgraph_api-0.2.2.dist-info/METADATA,sha256=bUoY2R3YkwXt9B4eWKQIVGe0VyQpT9L4b9PSRx88XxQ,4235
106
+ langgraph_api-0.2.2.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
107
+ langgraph_api-0.2.2.dist-info/entry_points.txt,sha256=3EYLgj89DfzqJHHYGxPH4A_fEtClvlRbWRUHaXO7hj4,77
108
+ langgraph_api-0.2.2.dist-info/RECORD,,