Skip to content

Update static functions in pregel/index.ts to match corresponding Python implementation#125

Merged
Andrew Nguonly (andrewnguonly) merged 12 commits intolangchain-ai:mainfrom
andrewnguonly:migrate-pregel-3
May 2, 2024
Merged

Update static functions in pregel/index.ts to match corresponding Python implementation#125
Andrew Nguonly (andrewnguonly) merged 12 commits intolangchain-ai:mainfrom
andrewnguonly:migrate-pregel-3

Conversation

@andrewnguonly
Copy link
Copy Markdown
Contributor

Summary

This PR updates static functions in pregel/index.ts to the match the corresponding Python implementation. These functions are used in the core stream() and invoke() methods of the Pregel class.

Implementation

  1. Implement _shouldInterrupt() (currently unused).
  2. Update _applyWrites() to match Python implementation.
  3. Remove _applyWritesFromView(). Removing the function did not break any tests. Not sure if this needs to be migrated.
  4. Update _prepareNextTasks() to match Python implementation. Note: The side effect from this function is removed and the calling code is updated to ensure that all existing tests pass.
  5. Implement _localRead() (replaced old implementation of read).
  6. Update ChannelRead and ChannelWrite to extend from RunnableCallable (this was a regression).
  7. Update @langchain/core and update RunnableCallable.invoke() to call mergeConfigs() (this was a regression).
  8. Implement streamChannelsList getter.

Next Steps

  1. Update _default(), stream(), and invoke() in Pregel class.

return newChannels;
}

export async function createCheckpoint<ValueType>(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function needs to be non-async in order for _localRead() to be patched in RunnableConfig and eventually called so it doesn't return a Promise.

Need to double check if this is ok.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep I think this doesn't have to be async


// Reassign nextCheckpoint to checkpoint because the subsequent implementation
// relies on side effects applied to checkpoint. Example: _applyWrites().
checkpoint = nextCheckpoint as Checkpoint;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is temporary. When stream() is reimplemented, I think this code will be removed.

// A copy of the checkpoint is created because `checkpoint` is defined with `let`.
// `checkpoint` can be mutated during loop execution and when used in a function,
// may cause unintended consequences.
const checkpointCopy = copyCheckpoint(checkpoint);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be temporary. When stream() is reimplemented, this code might be removed.

yield stepOutput;

if (typeof outputKeys !== "string") {
_applyWritesFromView(checkpoint, channels, stepOutput);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing this had no effect (i.e. all tests passed). Need to double check if I need to migrate it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah this is an api that used to exist in py but we removed, so good to remove here too

const newCheckpoint = createCheckpoint(checkpoint, channels);

// create a new copy of channels
const newChannels = Object.entries(channels).reduce(
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double check: This implementation is ported from a Python implementation that uses a context manager. What's the equivalent/preferred implementation in JS/TS?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is fine

triggers: this.triggers,
mapper: this.mapper,
writers: [...this.writers, coerceable as ChannelWrite],
bound: this.bound.pipe(coerceable),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a regression from a previous PR. It was only possible to do this once _prepareNextTasks() was updated.

@@ -1,4 +1,8 @@
import { Runnable, RunnableConfig } from "@langchain/core/runnables";
import {
mergeConfigs,
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mergeConfigs() was exported in @langchain/core 0.1.61.

@@ -48,9 +52,13 @@ export class RunnableCallable extends Runnable {

// TODO: mergeConfigs() from @langchain/core is not exported
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove comment

"author": "LangChain",
"license": "MIT",
"resolutions": {
"@langchain/core": "0.1.51"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need this in both package json files?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not 100% sure, but my assumption is because the @langchain/core dependencies are also needed in the examples directory, which is at the same level as langgraph.

@andrewnguonly Andrew Nguonly (andrewnguonly) merged commit a37e19d into langchain-ai:main May 2, 2024
@andrewnguonly Andrew Nguonly (andrewnguonly) deleted the migrate-pregel-3 branch May 2, 2024 15:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants