Tony20100/langchain_full huggingface dataset:
):
                # populates streamed_output in astream_log() output if needed
                iterator = stream_handler.tap_output_iter(run_manager.run_id, iterator)
            try:
                while True:
                    chunk: Output = context.run(next, iterator)  # type: ignore
                    yield chunk
                    if final_output_supported:
                        if final_output is None:
                            final_output = chunk
                        else:
                            try:
                                final_output = final_output + chunk  # type: ignore
                            except TypeError:
                                final_output = chunk
                                final_output_supported = False
                    else:
                        final_output = chunk
            except StopIteration:
                pass
            for ichunk in input_for_tracing:
                if final_input_supported:
                    if final_input is None:
                        final_input = ichunk
                    else:
                        try:
                            final_input = final_input + ichunk  # type: ignore
                        except TypeError:
                            final_input = ichunk
                            final_input_supported = False
                else:
                    final_input = ichunk
        except BaseException as e:
            run_manager.on_chain_error(e, inputs=final_input)
            raise
        else:
            run_manager.on_chain_end(final_output, inputs=final_input)
    async def _atransform_stream_with_config(
        self,
        input: AsyncIterator[Input],
        transformer: Union[
            Callable[[AsyncIterator[Input]], AsyncIterator[Output]],
            Callable[
                [AsyncIterator[Input], AsyncCallbackManagerForChainRun],
                AsyncIterator[Output],
            ],
            Callable[
                [
                    AsyncIterator[Input],
                    AsyncCallbackManagerForChainRun,
                    RunnableConfig,
                ],
                AsyncIterator[Output],
            ],
        ],
        config: Optional[RunnableConfig],
],
        ],
        config: Optional[RunnableConfig],
        run_type: Optional[str] = None,
        **kwargs: Optional[Any],
    ) -> AsyncIterator[Output]:
        """Helper method to transform an Async Iterator of Input values into an Async
        Iterator of Output values, with callbacks.
        Use this to implement `astream()` or `atransform()` in Runnable subclasses."""
        # Mixin that is used by both astream log and astream events implementation
        from langchain_core.tracers._streaming import _StreamingCallbackHandler
        # tee the input so we can iterate over it twice
        input_for_tracing, input_for_transform = atee(input, 2)
        # Start the input iterator to ensure the input runnable starts before this one
        final_input: Optional[Input] = await py_anext(input_for_tracing, None)
        final_input_supported = True
        final_output: Optional[Output] = None
        final_output_supported = True
        config = ensure_config(config)
        callback_manager = get_async_callback_manager_for_config(config)
        run_manager = await callback_manager.on_chain_start(
            dumpd(self),
            {"input": ""},
            run_type=run_type,
            name=config.get("run_name") or self.get_name(),
            run_id=config.pop("run_id", None),
        )
        try:
            child_config = patch_config(config, callbacks=run_manager.get_child())
            if accepts_config(transformer):
                kwargs["config"] = child_config
            if accepts_run_manager(transformer):
                kwargs["run_manager"] = run_manager
            context = copy_context()
            context.run(_set_config_context, child_config)
            iterator = context.run(transformer, input_for_transform, **kwargs)  # type: ignore[arg-type]
if stream_handler := next(
                (
                    cast(_StreamingCallbackHandler, h)
                    for h in run_manager.handlers
                    # instance check OK here, it's a mixin
                    if isinstance(h, _StreamingCallbackHandler)  # type: ignore[misc]
                ),
                None,
            ):
                # populates streamed_output in astream_log() output if needed
                iterator = stream_handler.tap_output_aiter(run_manager.run_id, iterator)
            try:
                while True:
                    if accepts_context(asyncio.create_task):
                        chunk: Output = await asyncio.create_task(  # type: ignore[call-arg]
                            py_anext(iterator),  # type: ignore[arg-type]
                            context=context,
                        )
                    else:
                        chunk = cast(Output, await py_anext(iterator))
                    yield chunk
                    if final_output_supported:
                        if final_output is None:
                            final_output = chunk
                        else:
                            try:
                                final_output = final_output + chunk  # type: ignore
                            except TypeError:
                                final_output = chunk
                                final_output_supported = False
                    else:
                        final_output = chunk
            except StopAsyncIteration:
                pass
            async for ichunk in input_for_tracing:
                if final_input_supported:
                    if final_input is None:
                        final_input = ichunk
                    else:
                        try:
                            final_input = final_input + ichunk  # type: ignore[operator]
                        except TypeError:
                            final_input = ichunk
                            final_input_supported = False
                else:
                    final_input = ichunk
        except BaseException as e:
            await run_manager.on_chain_error(e, inputs=final_input)
            raise
        else:
raise
        else:
            await run_manager.on_chain_end(final_output, inputs=final_input)
[docs]class RunnableSerializable(Serializable, Runnable[Input, Output]):
    """Runnable that can be serialized to JSON."""
    name: Optional[str] = None
    """The name of the runnable. Used for debugging and tracing."""
[docs]    def to_json(self) -> Union[SerializedConstructor, SerializedNotImplemented]:
        """Serialize the runnable to JSON."""
        dumped = super().to_json()
        try:
            dumped["name"] = self.get_name()
            dumped["graph"] = self.get_graph().to_json()
        except Exception:
            pass
        return dumped
[docs]    def configurable_fields(
        self, **kwargs: AnyConfigurableField
    ) -> RunnableSerializable[Input, Output]:
        """Configure particular runnable fields at runtime.
        .. code-block:: python
            from langchain_core.runnables import ConfigurableField
            from langchain_openai import ChatOpenAI
            model = ChatOpenAI(max_tokens=20).configurable_fields(
                max_tokens=ConfigurableField(
                    id="output_token_number",
                    name="Max tokens in the output",
                    description="The maximum number of tokens in the output",
                )
            )
            # max_tokens = 20
            print(
                "max_tokens_20: ",
                model.invoke("tell me something about chess").content
            )
            # max_tokens = 200
            print("max_tokens_200: ", model.with_config(
                configurable={"output_token_number": 200}
                ).invoke("tell me something about chess").content
            )
        """
        from langchain_core.runnables.configurable import RunnableConfigurableFields
        for key in kwargs:
for key in kwargs:
            if key not in self.__fields__:
                raise ValueError(
                    f"Configuration key {key} not found in {self}: "
                    f"available keys are {self.__fields__.keys()}"
                )
        return RunnableConfigurableFields(default=self, fields=kwargs)
[docs]    def configurable_alternatives(
        self,
        which: ConfigurableField,
        *,
        default_key: str = "default",
        prefix_keys: bool = False,
        **kwargs: Union[Runnable[Input, Output], Callable[[], Runnable[Input, Output]]],
    ) -> RunnableSerializable[Input, Output]:
        """Configure alternatives for runnables that can be set at runtime.
        .. code-block:: python
            from langchain_anthropic import ChatAnthropic
            from langchain_core.runnables.utils import ConfigurableField
            from langchain_openai import ChatOpenAI
            model = ChatAnthropic(
                model_name="claude-3-sonnet-20240229"
            ).configurable_alternatives(
                ConfigurableField(id="llm"),
                default_key="anthropic",
                openai=ChatOpenAI()
            )
            # uses the default model ChatAnthropic
            print(model.invoke("which organization created you?").content)
            # uses ChatOpenAI
            print(
                model.with_config(
                    configurable={"llm": "openai"}
                ).invoke("which organization created you?").content
            )
        """
        from langchain_core.runnables.configurable import (
            RunnableConfigurableAlternatives,
        )
        return RunnableConfigurableAlternatives(
            which=which,
            default=self,
            alternatives=kwargs,
            default_key=default_key,
default=self,
            alternatives=kwargs,
            default_key=default_key,
            prefix_keys=prefix_keys,
        )
def _seq_input_schema(
    steps: List[Runnable[Any, Any]], config: Optional[RunnableConfig]
) -> Type[BaseModel]:
    from langchain_core.runnables.passthrough import RunnableAssign, RunnablePick
    first = steps[0]
    if len(steps) == 1:
        return first.get_input_schema(config)
    elif isinstance(first, RunnableAssign):
        next_input_schema = _seq_input_schema(steps[1:], config)
        if not next_input_schema.__custom_root_type__:
            # it's a dict as expected
            return create_model(  # type: ignore[call-overload]
                "RunnableSequenceInput",
                **{
                    k: (v.annotation, v.default)
                    for k, v in next_input_schema.__fields__.items()
                    if k not in first.mapper.steps__
                },
            )
    elif isinstance(first, RunnablePick):
        return _seq_input_schema(steps[1:], config)
    return first.get_input_schema(config)
def _seq_output_schema(
    steps: List[Runnable[Any, Any]], config: Optional[RunnableConfig]
) -> Type[BaseModel]:
    from langchain_core.runnables.passthrough import RunnableAssign, RunnablePick
    last = steps[-1]
    if len(steps) == 1:
        return last.get_input_schema(config)
    elif isinstance(last, RunnableAssign):
        mapper_output_schema = last.mapper.get_output_schema(config)
        prev_output_schema = _seq_output_schema(steps[:-1], config)
        if not prev_output_schema.__custom_root_type__:
            # it's a dict as expected
# it's a dict as expected
            return create_model(  # type: ignore[call-overload]
                "RunnableSequenceOutput",
                **{
                    **{
                        k: (v.annotation, v.default)
                        for k, v in prev_output_schema.__fields__.items()
                    },
                    **{
                        k: (v.annotation, v.default)
                        for k, v in mapper_output_schema.__fields__.items()
                    },
                },
            )
    elif isinstance(last, RunnablePick):
        prev_output_schema = _seq_output_schema(steps[:-1], config)
        if not prev_output_schema.__custom_root_type__:
            # it's a dict as expected
            if isinstance(last.keys, list):
                return create_model(  # type: ignore[call-overload]
                    "RunnableSequenceOutput",
                    **{
                        k: (v.annotation, v.default)
                        for k, v in prev_output_schema.__fields__.items()
                        if k in last.keys
                    },
                )
            else:
                field = prev_output_schema.__fields__[last.keys]
                return create_model(  # type: ignore[call-overload]
                    "RunnableSequenceOutput",
                    __root__=(field.annotation, field.default),
                )
    return last.get_output_schema(config)
[docs]class RunnableSequence(RunnableSerializable[Input, Output]):
    """Sequence of Runnables, where the output of each is the input of the next.
    RunnableSequence is the most important composition operator in LangChain as it is
    used in virtually every chain.
    A RunnableSequence can be instantiated directly or more commonly by using the `|`
    operator where either the left or right operands (or both) must be a Runnable.
operator where either the left or right operands (or both) must be a Runnable.
    Any RunnableSequence automatically supports sync, async, batch.
    The default implementations of `batch` and `abatch` utilize threadpools and
    asyncio gather and will be faster than naive invocation of invoke or ainvoke
    for IO bound Runnables.
    Batching is implemented by invoking the batch method on each component of the
    RunnableSequence in order.
    A RunnableSequence preserves the streaming properties of its components, so if all
    components of the sequence implement a `transform` method -- which
    is the method that implements the logic to map a streaming input to a streaming
    output -- then the sequence will be able to stream input to output!
    If any component of the sequence does not implement transform then the
    streaming will only begin after this component is run. If there are
    multiple blocking components, streaming begins after the last one.
    Please note: RunnableLambdas do not support `transform` by default! So if
        you need to use a RunnableLambdas be careful about where you place them in a
        RunnableSequence (if you need to use the .stream()/.astream() methods).
        If you need arbitrary logic and need streaming, you can subclass
        Runnable, and implement `transform` for whatever logic you need.
    Here is a simple example that uses simple functions to illustrate the use of
    RunnableSequence:
        .. code-block:: python
            from langchain_core.runnables import RunnableLambda
            def add_one(x: int) -> int:
                return x + 1
            def mul_two(x: int) -> int:
                return x * 2
            runnable_1 = RunnableLambda(add_one)
            runnable_2 = RunnableLambda(mul_two)
runnable_2 = RunnableLambda(mul_two)
            sequence = runnable_1 | runnable_2
            # Or equivalently:
            # sequence = RunnableSequence(first=runnable_1, last=runnable_2)
            sequence.invoke(1)
            await sequence.ainvoke(1)
            sequence.batch([1, 2, 3])
            await sequence.abatch([1, 2, 3])
    Here's an example that uses streams JSON output generated by an LLM:
        .. code-block:: python
            from langchain_core.output_parsers.json import SimpleJsonOutputParser
            from langchain_openai import ChatOpenAI
            prompt = PromptTemplate.from_template(
                'In JSON format, give me a list of {topic} and their '
                'corresponding names in French, Spanish and in a '
                'Cat Language.'
            )
            model = ChatOpenAI()
            chain = prompt | model | SimpleJsonOutputParser()
            async for chunk in chain.astream({'topic': 'colors'}):
                print('-')  # noqa: T201
                print(chunk, sep='', flush=True)  # noqa: T201
    """
    # The steps are broken into first, middle and last, solely for type checking
    # purposes. It allows specifying the `Input` on the first type, the `Output` of
    # the last type.
    first: Runnable[Input, Any]
    """The first runnable in the sequence."""
    middle: List[Runnable[Any, Any]] = Field(default_factory=list)
    """The middle runnables in the sequence."""
    last: Runnable[Any, Output]
    """The last runnable in the sequence."""
    def __init__(
        self,
        *steps: RunnableLike,
def __init__(
        self,
        *steps: RunnableLike,
        name: Optional[str] = None,
        first: Optional[Runnable[Any, Any]] = None,
        middle: Optional[List[Runnable[Any, Any]]] = None,
        last: Optional[Runnable[Any, Any]] = None,
    ) -> None:
        """Create a new RunnableSequence.
        Args:
            steps: The steps to include in the sequence.
        """
        steps_flat: List[Runnable] = []
        if not steps:
            if first is not None and last is not None:
                steps_flat = [first] + (middle or []) + [last]
        for step in steps:
            if isinstance(step, RunnableSequence):
                steps_flat.extend(step.steps)
            else:
                steps_flat.append(coerce_to_runnable(step))
        if len(steps_flat) < 2:
            raise ValueError(
                f"RunnableSequence must have at least 2 steps, got {len(steps_flat)}"
            )
        super().__init__(  # type: ignore[call-arg]
            first=steps_flat[0],
            middle=list(steps_flat[1:-1]),
            last=steps_flat[-1],
            name=name,
        )
[docs]    @classmethod
    def get_lc_namespace(cls) -> List[str]:
        """Get the namespace of the langchain object."""
        return ["langchain", "schema", "runnable"]
    @property
    def steps(self) -> List[Runnable[Any, Any]]:
        """All the runnables that make up the sequence in order."""
        return [self.first] + self.middle + [self.last]
[docs]    @classmethod
    def is_lc_serializable(cls) -> bool:
[docs]    @classmethod
    def is_lc_serializable(cls) -> bool:
        return True
    class Config:
        arbitrary_types_allowed = True
    @property
    def InputType(self) -> Type[Input]:
        return self.first.InputType
    @property
    def OutputType(self) -> Type[Output]:
        return self.last.OutputType
[docs]    def get_input_schema(
        self, config: Optional[RunnableConfig] = None
    ) -> Type[BaseModel]:
        return _seq_input_schema(self.steps, config)
[docs]    def get_output_schema(
        self, config: Optional[RunnableConfig] = None
    ) -> Type[BaseModel]:
        return _seq_output_schema(self.steps, config)
    @property
    def config_specs(self) -> List[ConfigurableFieldSpec]:
        from langchain_core.beta.runnables.context import (
            CONTEXT_CONFIG_PREFIX,
            _key_from_id,
        )
        # get all specs
        all_specs = [
            (spec, idx)
            for idx, step in enumerate(self.steps)
            for spec in step.config_specs
        ]
        # calculate context dependencies
        specs_by_pos = groupby(
            [tup for tup in all_specs if tup[0].id.startswith(CONTEXT_CONFIG_PREFIX)],
            lambda x: x[1],
        )
        next_deps: Set[str] = set()
        deps_by_pos: Dict[int, Set[str]] = {}
        for pos, specs in specs_by_pos:
            deps_by_pos[pos] = next_deps
            next_deps = next_deps | {spec[0].id for spec in specs}
        # assign context dependencies
        for pos, (spec, idx) in enumerate(all_specs):
for pos, (spec, idx) in enumerate(all_specs):
            if spec.id.startswith(CONTEXT_CONFIG_PREFIX):
                all_specs[pos] = (
                    ConfigurableFieldSpec(
                        id=spec.id,
                        annotation=spec.annotation,
                        name=spec.name,
                        default=spec.default,
                        description=spec.description,
                        is_shared=spec.is_shared,
                        dependencies=[
                            d
                            for d in deps_by_pos[idx]
                            if _key_from_id(d) != _key_from_id(spec.id)
                        ]
                        + (spec.dependencies or []),
                    ),
                    idx,
                )
        return get_unique_config_specs(spec for spec, _ in all_specs)
[docs]    def get_graph(self, config: Optional[RunnableConfig] = None) -> Graph:
        from langchain_core.runnables.graph import Graph
        graph = Graph()
        for step in self.steps:
            current_last_node = graph.last_node()
            step_graph = step.get_graph(config)
            if step is not self.first:
                step_graph.trim_first_node()
            if step is not self.last:
                step_graph.trim_last_node()
            step_first_node, _ = graph.extend(step_graph)
            if not step_first_node:
                raise ValueError(f"Runnable {step} has no first node")
            if current_last_node:
                graph.add_edge(current_last_node, step_first_node)
        return graph
    def __repr__(self) -> str:
        return "\n| ".join(
            repr(s) if i == 0 else indent_lines_after_first(repr(s), "| ")
            for i, s in enumerate(self.steps)
        )
    def __or__(
        self,
        other: Union[
            Runnable[Any, Other],
self,
        other: Union[
            Runnable[Any, Other],
            Callable[[Any], Other],
            Callable[[Iterator[Any]], Iterator[Other]],
            Mapping[str, Union[Runnable[Any, Other], Callable[[Any], Other], Any]],
        ],
    ) -> RunnableSerializable[Input, Other]:
        if isinstance(other, RunnableSequence):
            return RunnableSequence(
                self.first,
                *self.middle,
                self.last,
                other.first,
                *other.middle,
                other.last,
                name=self.name or other.name,
            )
        else:
            return RunnableSequence(
                self.first,
                *self.middle,
                self.last,
                coerce_to_runnable(other),
                name=self.name,
            )
    def __ror__(
        self,
        other: Union[
            Runnable[Other, Any],
            Callable[[Other], Any],
            Callable[[Iterator[Other]], Iterator[Any]],
            Mapping[str, Union[Runnable[Other, Any], Callable[[Other], Any], Any]],
        ],
    ) -> RunnableSerializable[Other, Output]:
        if isinstance(other, RunnableSequence):
            return RunnableSequence(
                other.first,
                *other.middle,
                other.last,
                self.first,
                *self.middle,
                self.last,
                name=other.name or self.name,
            )
        else:
            return RunnableSequence(
                coerce_to_runnable(other),
                self.first,
                *self.middle,
                self.last,
                name=self.name,
            )
[docs]    def invoke(
        self, input: Input, config: Optional[RunnableConfig] = None, **kwargs: Any
    ) -> Output: