Update Pregel files to match Python implementation: debug.ts, io.ts, read.ts, types.ts, write.ts#120
Conversation
langgraph/src/pregel/types.ts
Outdated
| input: any; | ||
| proc: Runnable; | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| writes: Array<[string, any]>; // TODO: Array type may need to be changed |
There was a problem hiding this comment.
The Python implementation uses collections.deque and the implementation of Pregel depends on the deque APIs. I need to figure out the appropriate type later.
There was a problem hiding this comment.
we use deque in python for thread safety. in js fine to use array
langgraph/src/pregel/types.ts
Outdated
| /** | ||
| * Nodes to execute in the next step, if any | ||
| */ | ||
| next: [string]; |
There was a problem hiding this comment.
Double check: This needs to be Array<string>.
There was a problem hiding this comment.
yes current type is wrong
| default: null, | ||
| annotation: "TYPE_SEND", | ||
| isShared: true, | ||
| isShared: false, |
There was a problem hiding this comment.
The default value is false in the Python implementation.
| } | ||
|
|
||
| static registerWriter(runnable: Runnable): ChannelWrite { | ||
| return runnable as ChannelWrite; |
There was a problem hiding this comment.
Double check: Not used at the moment, but need to double check that this is the desired implementation.
There was a problem hiding this comment.
It's not, but you can fix it later
|
|
||
| static isWriter(runnable: RunnableLike): boolean { | ||
| // eslint-disable-next-line no-instanceof/no-instanceof | ||
| return runnable instanceof ChannelWrite; |
There was a problem hiding this comment.
Double check: Currently used in PregelNode.pipe(). Need to double check that this is the desired implementation.
| } | ||
| } | ||
|
|
||
| function _readChannel( |
There was a problem hiding this comment.
This is moved to io.ts.
| if (proc.when === undefined || proc.when(val)) { | ||
| tasks.push([proc, val, name]); | ||
| } | ||
| tasks.push([proc, val, name]); |
There was a problem hiding this comment.
I don't know if this is valid, but all of the existing tests are passing.
There was a problem hiding this comment.
why would it not be valid?
There was a problem hiding this comment.
I was just comparing with the current Python implementation which relies on the for_execution API, which isn't implemented yet in JS.
| lc_graph_name = "ChannelInvoke"; | ||
| lc_graph_name = "PregelNode"; | ||
|
|
||
| channels: Record<string, string> | string; |
There was a problem hiding this comment.
channels is supposed to be type Record<string, string> | string[], but I couldn't make this change without breaking a significant amount of tests. I'll make this update when I update the Pregel class.
langgraph/src/pregel/read.ts
Outdated
| writers?: Runnable[]; | ||
| tags?: string[]; | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| bound?: Runnable<any, any>; |
There was a problem hiding this comment.
Should this be Runnable<RunInput, RunOutput>?
langgraph/src/pregel/read.ts
Outdated
| when?: (args: any) => boolean; | ||
| config?: RunnableConfig; | ||
| mapper?: (args: any) => any; | ||
| writers?: Runnable[]; |
There was a problem hiding this comment.
Should this be Runnable<RunInput, RunOutput>[]?
There was a problem hiding this comment.
This one should be Runnable<RunOutput, RunOutput>[]
| triggers: string[] = []; | ||
|
|
||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| when?: (args: any) => boolean; |
There was a problem hiding this comment.
Removed all instances and usages of when. I think this was a deprecated feature?
There was a problem hiding this comment.
Yep this not used anymore
| triggers: this.triggers, | ||
| mapper: this.mapper, | ||
| writers: [...this.writers, coerceable as ChannelWrite], | ||
| bound: this.bound.pipe(coerceable), |
There was a problem hiding this comment.
This diverges from the Python implementation. I couldn't get the existing tests to pass without piping coerceable. Any advice?
Python implementation: https://github.com/langchain-ai/langgraph/blob/main/langgraph/pregel/read.py#L201
There was a problem hiding this comment.
That's because you need other changes in Pregel class I think
There was a problem hiding this comment.
Is it ok to leave this change in for now?
There was a problem hiding this comment.
yes, but make a note to change this
| ): Generator<[string, any]> { | ||
| if (typeof inputChannels === "string") { | ||
| yield [inputChannels, chunk]; | ||
| if (chunk) { |
There was a problem hiding this comment.
This check was added in the Python implementation: https://github.com/andrewnguonly/langgraph/blob/main/langgraph/pregel/io.py#L52
langgraph/src/pregel/write.ts
Outdated
| .join(",")}>`; | ||
| super({ | ||
| ...{ channels, name }, | ||
| ...{ channels: writes, name }, |
There was a problem hiding this comment.
this should bewrites in super call too?
There was a problem hiding this comment.
Unexpected change by VSCode when applying the Rename Symbol action. I changed to ...{ writes, name } and everything seems to work the same.
Nuno Campos (nfcampos)
left a comment
There was a problem hiding this comment.
mostly lgtm, some minor comments
|
|
||
| const valuesAwaited = await Promise.all(values); | ||
|
|
||
| async _getWriteValues( |
There was a problem hiding this comment.
Nuno Campos (@nfcampos), the implementation of _getWriteValues() (and _write()) matches the Python implementation as specified in langchain-ai/langgraph#345. However, I only made the bare minimum changes in Pregel and StateGraph to make the existing tests pass.
I'll add a new test to match this one: https://github.com/langchain-ai/langgraph/pull/345/files#diff-9f99beb90b66284c77ac257b4c0dfc06dcb998302f7c6740d84759460f704f53
langgraph/src/tests/pregel.test.ts
Outdated
| }); | ||
|
|
||
| // TODO: fix this test | ||
| xit("can invoke a nested graph", async () => { |
There was a problem hiding this comment.
Nuno Campos (@nfcampos), I copied this test, but I haven't figured out where the fix needs to be in the existing implementation (which will probably be changed later). Ideally, I'd like to get this fixed/working before merging. I'll ask you for help in the morning.
…of Runnable if it is defined in graph state.
…hat exception is raised in method call.
Summary
The following files are updated (as much as possible) to match the corresponding Python implementation:
debug.ts,io.ts,read.ts,types.ts,write.ts. The goal is to update the files without breaking existing tests or adding new functionality that would require significant changes to thePregelclass.The implementation does not match exactly 1:1 with the Python implementation. I'll leave comments directly in the PR to note any differences.
Implementation
debug.ts: Small updates.io.ts: MovedreadChannel()function to this file. Added the following unused functionsreadChannels(),mapOutputValues(), andmapOutputUpdates().read.ts: RenamedChannelInvoketoPregelNode. Added more fields toPregelNode. RemovePregelNode.when. UpdatePregelNode.pipe()to support checkingChannelWrite.types.ts: New file created to match Python implementation.write.ts: AddChannelWrite.isWriter()andChannelWrite.registerWriter().RunnableCallableclass as part of fixing bug in Fix bug where saving a runnable or function in state object would misbehave langgraph#345. I haven't migrated all instances ofRunnableLambdatoRunnableCallableyet. Will do this in a subsequent PR.To Do
io.ts.functions.Next Steps
pregel/index.ts(PregelandChannelclasses).RunnableLambdatoRunnableCallable.pregel/validate.ts(I think).