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

Callbacks Refactor [base] #3256

Merged
merged 45 commits into from Apr 30, 2023
Merged

Callbacks Refactor [base] #3256

merged 45 commits into from Apr 30, 2023

Conversation

agola11
Copy link
Collaborator

@agola11 agola11 commented Apr 21, 2023

No description provided.

@agola11 agola11 changed the title callbacks refactor [1/n callbacks refactor [1/n] Apr 21, 2023
@agola11 agola11 changed the title callbacks refactor [1/n] Callbacks Refactor [1/n]: non abstract and fix repeated logic Apr 22, 2023
@agola11 agola11 changed the title Callbacks Refactor [1/n]: non abstract and fix repeated logic Callbacks Refactor [1/n]: add callbacks mixins, Apr 23, 2023
return _configure(cls, inheritable_callbacks, local_callbacks, verbose)


T = TypeVar("T", CallbackManager, AsyncCallbackManager)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can think of a better way to do this if it's ugly -- basically want to enforce with typing that typing among arguments and return value must be consistent

Copy link
Contributor

Choose a reason for hiding this comment

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

Makes sense to me

# There are many CallbackHandlers supported, such as
# from langchain.callbacks.streamlit import StreamlitCallbackHandler

callback_manager = CallbackManager([StreamingStdOutCallbackHandler()])
model = GPT4All(model="./models/gpt4all-model.bin", n_ctx=512, n_threads=8, callback_handler=callback_handler, verbose=True)
model = GPT4All(model="./models/gpt4all-model.bin", n_ctx=512, n_threads=8, callback_handler=callback_handler,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Was this line wrong anyway? In the previous line creating a callback_manager, then passing a callback_handler var (that I think doesn't exist) to a callback_handler arg that I also think doesn't exist

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh yeah, this was messed up by the pycharm refactoring tool

for handler in handlers:
self.add_handler(handler, inherit=inherit)

def set_handler(self, handler: BaseCallbackHandler, inherit=True) -> None:
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this method useful enough to exist?

token: str,
run_id: Optional[str] = None,
parent_run_id: Optional[str] = None,
**kwargs: Any,
Copy link
Collaborator

Choose a reason for hiding this comment

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

We don't have these kwargs in js, should we?

langchain/callbacks/base.py Outdated Show resolved Hide resolved
)
else:
callback_manager = inheritable_callbacks
callback_manager = copy.deepcopy(callback_manager)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why call deep copy directly here rather than the copy method?

Copy link
Contributor

@sliedes sliedes May 2, 2023

Choose a reason for hiding this comment

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

Indeed, I ran into this. What's the logic behind a copy here anyway? I'd assume many callback managers—definitely mine—maintain state that cannot be copied such as file handles, network connections, asyncio.Futures etc.

I don't know this code that well, but why even copy at all? It seems somewhat antithetical to the rationale of a callback manager that everything makes a copy of it.

(Not only speaking of the copying of the callback_manager but also all handlers few lines below.)

@agola11 agola11 changed the title Callbacks Refactor [1/n]: add callbacks mixins, Callbacks Refactor [base]: add callbacks mixins, Apr 26, 2023
@agola11 agola11 changed the title Callbacks Refactor [base]: add callbacks mixins, Callbacks Refactor [base] Apr 26, 2023
@@ -75,7 +69,8 @@ def _handle_event(
):
getattr(handler, event_name)(*args, **kwargs)
except Exception as e:
logging.error(f"Error in {event_name} callback: {e}")
# TODO: switch this to use logging
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure why we have to wait?

def tracing_enabled(
session_name: str = "default",
) -> Generator[TracerSession, None, None]:
"""Get OpenAI callback handler in a context manager."""

Choose a reason for hiding this comment

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

Incorrect docstring?

@agola11 agola11 merged commit d3ec00b into master Apr 30, 2023
9 checks passed
@agola11 agola11 deleted the ankush/callbacks-refactor branch April 30, 2023 18:14
lightshifted added a commit to Hedronstone/agent-actors that referenced this pull request Apr 30, 2023
Modified langchain dependency to prevent error caused by LangChain's recent callbacks refactor ([Callbacks Refactor [base] #3256](langchain-ai/langchain#3256))
samching pushed a commit to samching/langchain that referenced this pull request May 1, 2023
Co-authored-by: Nuno Campos <nuno@boringbits.io>
Co-authored-by: Davis Chase <130488702+dev2049@users.noreply.github.com>
Co-authored-by: Zander Chase <130414180+vowelparrot@users.noreply.github.com>
Co-authored-by: Harrison Chase <hw.chase.17@gmail.com>
@pors
Copy link
Contributor

pors commented May 2, 2023

@agola11 This was a breaking change. Is it documented somewhere how to migrate? In my case, I did the following:

from langchain.callbacks.base import AsyncCallbackManager

and replaced it with:

from langchain.callbacks.manager import AsyncCallbackManager

but it broke my app:

  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/langchain/chains/base.py", line 180, in acall
    raise e
  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/langchain/chains/base.py", line 174, in acall
    await self._acall(inputs, run_manager=run_manager)
  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/langchain/chains/llm.py", line 195, in _acall
    response = await self.agenerate([inputs], run_manager=run_manager)
  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/langchain/chains/llm.py", line 90, in agenerate
    return await self.llm.agenerate_prompt(
  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/langchain/llms/base.py", line 136, in agenerate_prompt
    return await self.agenerate(prompt_strings, stop=stop, callbacks=callbacks)
  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/langchain/llms/base.py", line 217, in agenerate
    callback_manager = AsyncCallbackManager.configure(
  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/langchain/callbacks/manager.py", line 667, in configure
    return _configure(cls, inheritable_callbacks, local_callbacks, verbose)
  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/langchain/callbacks/manager.py", line 701, in _configure
    callback_manager.add_handler(copy.deepcopy(handler), False)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 271, in _reconstruct
    state = deepcopy(state, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 231, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 271, in _reconstruct
    state = deepcopy(state, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 231, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 231, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 271, in _reconstruct
    state = deepcopy(state, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 146, in deepcopy
    y = copier(x, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 231, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 172, in deepcopy
    y = _reconstruct(x, memo, *rv)
  File "/Users/mark/.pyenv/versions/3.10.9/lib/python3.10/copy.py", line 272, in _reconstruct
    if hasattr(y, '__setstate__'):
  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/starlette/datastructures.py", line 702, in __getattr__
    return self._state[key]
  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/starlette/datastructures.py", line 702, in __getattr__
    return self._state[key]
  File "/Users/mark/.pyenv/versions/ve3109_fcc/lib/python3.10/site-packages/starlette/datastructures.py", line 702, in __getattr__
    return self._state[key]
  [Previous line repeated 949 more times]
RecursionError: maximum recursion depth exceeded

Help 😁

@agola11
Copy link
Collaborator Author

agola11 commented May 2, 2023

@pors -- can you send me a snipped of how you were using AsyncCallbackManager and what handlers you were using along with it? I'll be able to help you more

@pors
Copy link
Contributor

pors commented May 2, 2023

@agola11 The whole project is here: https://github.com/pors/langchain-chat-websockets/blob/main/query_data.py

The relevant code is largely based on https://github.com/hwchase17/chat-langchain, so the issue may also be there.

@agola11
Copy link
Collaborator Author

agola11 commented May 2, 2023

@pors okay thanks. Looking in a bit

@agola11
Copy link
Collaborator Author

agola11 commented May 2, 2023

Once this lands, your issue should be resolved: #3995 -- please comment if that's not the case

@pors
Copy link
Contributor

pors commented May 3, 2023

Thanks! It works again for me. I like the fast release schedule :)

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.

None yet

8 participants