Skip to content

Commit d7f1e8f

Browse files
committed
fix: recreate step management for langgraph integration
1 parent 3c29259 commit d7f1e8f

File tree

1 file changed

+26
-33
lines changed
  • typescript-sdk/integrations/langgraph/src

1 file changed

+26
-33
lines changed

typescript-sdk/integrations/langgraph/src/agent.ts

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ export class LangGraphAgent extends AbstractAgent {
125125
// @ts-expect-error no need to initialize subscriber right now
126126
subscriber: Subscriber<ProcessedEvents>;
127127
constantSchemaKeys: string[] = DEFAULT_SCHEMA_KEYS;
128-
activeStep?: string;
129128
config: LangGraphAgentConfig;
130129

131130
constructor(config: LangGraphAgentConfig) {
@@ -235,11 +234,6 @@ export class LangGraphAgent extends AbstractAgent {
235234
this.activeRun!.manuallyEmittedState = null;
236235

237236
const nodeNameInput = forwardedProps?.nodeName;
238-
this.activeRun!.nodeName = nodeNameInput;
239-
if (this.activeRun!.nodeName === "__end__") {
240-
this.activeRun!.nodeName = undefined;
241-
}
242-
243237
const threadId = inputThreadId ?? randomUUID();
244238

245239
if (!this.assistant) {
@@ -347,6 +341,7 @@ export class LangGraphAgent extends AbstractAgent {
347341
threadId,
348342
runId: input.runId,
349343
});
344+
this.handleNodeChange(nodeNameInput)
350345

351346
interrupts.forEach((interrupt) => {
352347
this.dispatchEvent({
@@ -400,11 +395,7 @@ export class LangGraphAgent extends AbstractAgent {
400395
threadId,
401396
runId: this.activeRun!.id,
402397
});
403-
404-
// In case of resume (interrupt), re-start resumed step
405-
if (forwardedProps?.command?.resume && this.activeRun!.nodeName) {
406-
this.startStep(this.activeRun!.nodeName);
407-
}
398+
this.handleNodeChange(nodeNameInput)
408399

409400
for await (let streamResponseChunk of streamResponse) {
410401
const subgraphsStreamEnabled = input.forwardedProps?.streamSubgraphs;
@@ -460,11 +451,7 @@ export class LangGraphAgent extends AbstractAgent {
460451
this.activeRun!.id = metadata.run_id;
461452

462453
if (currentNodeName && currentNodeName !== this.activeRun!.nodeName) {
463-
if (this.activeRun!.nodeName && this.activeRun!.nodeName !== nodeNameInput) {
464-
this.endStep();
465-
}
466-
467-
this.startStep(currentNodeName);
454+
this.handleNodeChange(currentNodeName)
468455
}
469456

470457
shouldExit =
@@ -482,7 +469,7 @@ export class LangGraphAgent extends AbstractAgent {
482469
// we only want to update the node name under certain conditions
483470
// since we don't need any internal node names to be sent to the frontend
484471
if (this.activeRun!.graphInfo?.["nodes"].some((node) => node.id === currentNodeName)) {
485-
this.activeRun!.nodeName = currentNodeName;
472+
this.handleNodeChange(currentNodeName)
486473
}
487474

488475
updatedState.values = this.activeRun!.manuallyEmittedState ?? latestStateValues;
@@ -523,6 +510,7 @@ export class LangGraphAgent extends AbstractAgent {
523510
const isEndNode = state.next.length === 0;
524511
const writes = state.metadata?.writes ?? {};
525512

513+
// Initialize a new node name to use in the next if block
526514
let newNodeName = this.activeRun!.nodeName!;
527515

528516
if (!interrupts?.length) {
@@ -539,12 +527,10 @@ export class LangGraphAgent extends AbstractAgent {
539527
});
540528
});
541529

542-
if (this.activeRun!.nodeName != newNodeName) {
543-
this.endStep();
544-
this.startStep(newNodeName);
545-
}
530+
this.handleNodeChange(newNodeName);
531+
// Immediately turn off new step
532+
this.handleNodeChange(undefined);
546533

547-
this.endStep();
548534
this.dispatchEvent({
549535
type: EventType.STATE_SNAPSHOT,
550536
snapshot: this.getStateSnapshot(state),
@@ -1017,28 +1003,35 @@ export class LangGraphAgent extends AbstractAgent {
10171003
};
10181004
}
10191005

1020-
startStep(nodeName: string) {
1021-
if (this.activeStep) {
1022-
this.endStep();
1006+
handleNodeChange(nodeName: string | undefined) {
1007+
if (nodeName === "__end__") {
1008+
nodeName = undefined;
10231009
}
1010+
if (nodeName !== this.activeRun?.nodeName) {
1011+
// End current step
1012+
if (this.activeRun?.nodeName) {
1013+
this.endStep();
1014+
}
1015+
// If we actually got a node name, start a new step
1016+
if (nodeName) {
1017+
this.startStep(nodeName);
1018+
}
1019+
}
1020+
this.activeRun!.nodeName = nodeName;
1021+
}
1022+
1023+
startStep(nodeName: string) {
10241024
this.dispatchEvent({
10251025
type: EventType.STEP_STARTED,
10261026
stepName: nodeName,
10271027
});
1028-
this.activeRun!.nodeName = nodeName;
1029-
this.activeStep = nodeName;
10301028
}
10311029

10321030
endStep() {
1033-
if (!this.activeStep) {
1034-
throw new Error("No active step to end");
1035-
}
10361031
this.dispatchEvent({
10371032
type: EventType.STEP_FINISHED,
1038-
stepName: this.activeRun!.nodeName! ?? this.activeStep,
1033+
stepName: this.activeRun!.nodeName!,
10391034
});
1040-
this.activeRun!.nodeName = undefined;
1041-
this.activeStep = undefined;
10421035
}
10431036

10441037
async getCheckpointByMessage(

0 commit comments

Comments
 (0)