Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(langgraph): functional API #793

Merged
merged 30 commits into from
Jan 29, 2025
Merged

feat(langgraph): functional API #793

merged 30 commits into from
Jan 29, 2025

Conversation

benjamincburns
Copy link
Contributor

@benjamincburns benjamincburns commented Jan 21, 2025

feat(langgraph): Add Functional API

This PR introduces a new functional API to langgraphjs that provides a simpler, more intuitive way to create and compose tasks in a graph. The changes focus on improving developer experience while maintaining the power and flexibility of the existing graph-based system.

Key Changes

1. New Functional API Components

  • Added new task and entrypoint functions for creating graph nodes
  • Introduced experimental TaskOptions and EntrypointOptions interfaces
  • Added support for retry policies at the task level

2. Configuration and Constants Updates

  • Added new configuration keys for the functional API (CONFIG_KEY_CALL)
  • Introduced new control flow constants (NO_WRITES, RETURN)
  • Enhanced type safety for the SendInterface validation

3. Pregel Engine Improvements

  • Modified task handling to support functional API calls
  • Enhanced error handling and null value checking in task writes
  • Updated the IGNORE set to include new control flow signals

4. Type System Enhancements

  • Added new types for task paths and calls
  • Improved type safety throughout the codebase

Implementation Details

The implementation focuses on maintaining backward compatibility while introducing the new functional API. Key architectural decisions include:

  1. Using the Pregel engine as the underlying execution system
  2. Maintaining the existing channel-based communication system
  3. Adding proper TypeScript types for improved developer experience
  4. Implementing proper error handling and validation

Example Usage

import { task, entrypoint } from "@langchain/langgraph";

// Define a task with optional retry policy
const processData = task(
  "process",
  async (data) => {
    // Process the data
    return result;
  },
  { retry: { maxAttempts: 3 } }
);

// Create an entrypoint
const workflow = entrypoint({ name: "main" }, async (input) => {
  const result = await processData(input);
  return result;
});

Breaking Changes

None. This is a purely additive change that maintains compatibility with existing code.

Testing

Added new test files and cases to cover the functional API functionality:

  • func.test.ts for testing the new API
  • Additional test coverage in existing test files

libs/langgraph/src/pregel/runner.ts Show resolved Hide resolved
libs/langgraph/src/pregel/types.ts Show resolved Hide resolved
libs/langgraph/src/func.ts Outdated Show resolved Hide resolved
@benjamincburns benjamincburns force-pushed the ben/functional-api branch 2 times, most recently from 9ae5ec9 to b666c47 Compare January 21, 2025 23:34
libs/langgraph/src/pregel/types.ts Outdated Show resolved Hide resolved
libs/langgraph/src/pregel/call.ts Outdated Show resolved Hide resolved
libs/langgraph/src/constants.ts Outdated Show resolved Hide resolved
/**
* Wraps a function in a task that can be retried
*
* !!! warning "Experimental"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we actually want this warning in? Seems harsh

Copy link
Contributor

Choose a reason for hiding this comment

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

Yea this is not the copy I'd want, I think better to say something like

!!! warning "Beta"
This is a new API which might evolve over the next few weeks.
We plan to mark it as stable by X day [next 3 weeks]

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I lifted it directly from the python lib. The @experimental and @beta tsdoc tags should ideally convey the same meaning, although per the spec they may be removed by tooling on non-beta releases. I haven't checked the docs build yet to see what actually happens, and whether we can configure this, so I left it in for now as a sort of reminder to myself.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@nfcampos @eyurtsev is the current copy in the python lib what we're happy to go with here?

for reference:

    !!! warning "Beta"
        The Functional API is currently in beta and is subject to change.

libs/langgraph/src/func.ts Outdated Show resolved Hide resolved
libs/langgraph/src/pregel/algo.ts Show resolved Hide resolved
libs/langgraph/src/pregel/call.ts Outdated Show resolved Hide resolved
libs/langgraph/src/pregel/call.ts Outdated Show resolved Hide resolved
@benjamincburns benjamincburns force-pushed the ben/functional-api branch 7 times, most recently from d9328c1 to e110fb1 Compare January 23, 2025 20:01
@benjamincburns benjamincburns force-pushed the ben/functional-api branch 4 times, most recently from e8ef2f4 to 41e730b Compare January 28, 2025 03:49
Comment on lines 49 to 72
export const RESERVED = [
TAG_HIDDEN,
INPUT,
INTERRUPT,
RESUME,
ERROR,
NO_WRITES,
TASKS,

// reserved config.configurable keys
CONFIG_KEY_SEND,
CONFIG_KEY_READ,
CONFIG_KEY_CHECKPOINTER,
CONFIG_KEY_STREAM,
CONFIG_KEY_RESUMING,
CONFIG_KEY_TASK_ID,
CONFIG_KEY_STREAM,
CONFIG_KEY_CALL,
CONFIG_KEY_RESUME_VALUE,
CONFIG_KEY_SCRATCHPAD,
CONFIG_KEY_PREVIOUS_STATE,
CONFIG_KEY_CHECKPOINT_MAP,
INPUT,
CONFIG_KEY_CHECKPOINT_NS,
CONFIG_KEY_CHECKPOINT_ID,
];
Copy link
Contributor Author

Choose a reason for hiding this comment

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

aligned order w/ python code so it's easier to check

@benjamincburns benjamincburns marked this pull request as ready for review January 28, 2025 08:58
Comment on lines +418 to +433
export function skipIf(condition: () => boolean): typeof it | typeof it.skip {
if (condition()) {
return it.skip;
} else {
return it;
}
}

export async function dumpDebugStream<
Nn extends StrRecord<string, PregelNode>,
Cc extends StrRecord<string, BaseChannel | ManagedValueSpec>,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
ConfigurableFieldType extends Record<string, any> = StrRecord<string, any>,
InputType = PregelInputType,
OutputType = PregelOutputType
>(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

these are actually unused now, but I left them in, in case they're handy.

jacoblee93
jacoblee93 previously approved these changes Jan 28, 2025
Copy link
Collaborator

@jacoblee93 jacoblee93 left a comment

Choose a reason for hiding this comment

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

Overall looks good to me, will leave for @nfcampos for final review

libs/langgraph/src/func/index.ts Outdated Show resolved Hide resolved
libs/langgraph/src/func/index.ts Outdated Show resolved Hide resolved
libs/langgraph/src/func/index.ts Outdated Show resolved Hide resolved
libs/langgraph/src/func/types.ts Show resolved Hide resolved
libs/langgraph/src/pregel/index.ts Outdated Show resolved Hide resolved
libs/langgraph/src/pregel/utils/config.ts Show resolved Hide resolved
@benjamincburns benjamincburns merged commit 894994a into main Jan 29, 2025
19 checks passed
@benjamincburns benjamincburns deleted the ben/functional-api branch January 29, 2025 00:56
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.

3 participants