Expose configurables through RemoteRunnable #47

Open
opened 2026-02-16 00:18:18 -05:00 by yindo · 1 comment
Owner

Originally created by @Vinno97 on GitHub (Nov 23, 2023).

For local runnables, you can use runnable.config_specs to get a list of all configurable fields. The RemoteRunnable doesn't expose these, even though it technically has the correct information via /config_schema endpoint. The same can be said for Input and Output with input_schema and output_schema, respectively.

Loading these endpoints (lazily) would enable better compatibility with applications that may rely on this. In my case, I automatically expose some of my chain's options through a UI when they're configurable. This now doesn't work when I use langserve.

Originally created by @Vinno97 on GitHub (Nov 23, 2023). For local runnables, you can use `runnable.config_specs` to get a list of all configurable fields. The `RemoteRunnable` doesn't expose these, even though it technically has the correct information via `/config_schema` endpoint. The same can be said for `Input` and `Output` with `input_schema` and `output_schema`, respectively. Loading these endpoints (lazily) would enable better compatibility with applications that may rely on this. In my case, I automatically expose some of my chain's options through a UI when they're configurable. This now doesn't work when I use langserve.
Author
Owner

@Vinno97 commented on GitHub (Nov 23, 2023):

I don't know of an elegant way to map the "annotations" field back to Python types, but this seems to work for my chains:

def json_annotation_to_type(annotation: str) -> type:
    if annotation == "string":
        return str
    elif annotation == "boolean":
        return bool
    elif annotation == "integer":
        return int
    elif annotation == "number":
        return float
    elif annotation == "array":
        return list
    raise NotImplementedError(f'Can\'t convert annotation "{annotation}" to type')


class ConfigurableRemoteRunnable(RemoteRunnable):
    @property
    def config_specs(self) -> list[ConfigurableFieldSpec]:
        if getattr(self, "_config_specs", None) is None:
            schema = self.sync_client.get("/config_schema").json()

            fields = schema["definitions"]["Configurable"]["properties"]
            self._config_specs = []
            for field_id, field_props in fields.items():
                self._config_specs.append(
                    ConfigurableFieldSpec(
                        id=field_id,
                        name=field_props["title"],
                        description=field_props["description"],
                        default=field_props.get("default", None),
                        annotation=json_annotation_to_type(field_props["type"]),
                    )
                )

        return self._config_specs


@Vinno97 commented on GitHub (Nov 23, 2023): I don't know of an elegant way to map the "annotations" field back to Python types, but this seems to work for my chains: ```py def json_annotation_to_type(annotation: str) -> type: if annotation == "string": return str elif annotation == "boolean": return bool elif annotation == "integer": return int elif annotation == "number": return float elif annotation == "array": return list raise NotImplementedError(f'Can\'t convert annotation "{annotation}" to type') class ConfigurableRemoteRunnable(RemoteRunnable): @property def config_specs(self) -> list[ConfigurableFieldSpec]: if getattr(self, "_config_specs", None) is None: schema = self.sync_client.get("/config_schema").json() fields = schema["definitions"]["Configurable"]["properties"] self._config_specs = [] for field_id, field_props in fields.items(): self._config_specs.append( ConfigurableFieldSpec( id=field_id, name=field_props["title"], description=field_props["description"], default=field_props.get("default", None), annotation=json_annotation_to_type(field_props["type"]), ) ) return self._config_specs ```
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/langserve#47