Skip to content

tdfs4ds.agent

tdfs4ds.agent

__all__ module-attribute

__all__ = ['query_optimizer', 'aquery_optimizer', 'skill_optimize_query', 'skill_generate_candidates', 'display_optimization_result', 'skill_simplify_query', 'simplify_query', 'consumer_agent', 'build_graph', 'reset_consumer_agent', 'intent_classifier', '_build_intent_model', 'list_instruct_models', 'get_data_domain', 'detect_data_domain_for_object', 'skill_lineage', 'skill_explain', 'list_embedding_models', 'skill_search', 'skill_definition', 'skill_usage', 'skill_freshness', 'skill_summary', 'synthesize_answer', 'IntentResult', 'get_embeddings', 'build_vector_index', 'search_vector_index', 'launch_chatbot', 'launch_chatbot_with_index', 'launch_chatbot_app']

IntentResult

Bases: BaseModel

Structured output for intent classification (hardwired fallback — all 10 intents).

intent instance-attribute

intent: Literal['SEARCH', 'DEFINITION', 'USAGE', 'FRESHNESS', 'SUMMARY', 'DATA_DOMAINS', 'FEASIBILITY', 'LINEAGE', 'EXPLAIN', 'DATASET', 'BUILD_DATASET', 'RECAP', 'HELP', 'OUT_OF_SCOPE']

object_name class-attribute instance-attribute

object_name: Optional[str] = Field(None, description='Name of any documented item mentioned: a feature, a documented column, a table, a view, or a dataset')

domain class-attribute instance-attribute

domain: Optional[str] = Field(None, description='DATA_DOMAIN — the feature-store project/namespace that isolates features; NOT a feature theme. Copy verbatim if the user names one, else null.')

entity_name class-attribute instance-attribute

entity_name: Optional[str] = Field(None, description='Entity / granularity level if the user names one (the key a feature is computed for), copied verbatim')

user_preferences class-attribute instance-attribute

user_preferences: Optional[dict] = Field(None, description="User preferences or constraints (e.g. {'currency': 'USD', 'output_format': 'JSON'})")

sub_intents class-attribute instance-attribute

sub_intents: Optional[List['_SubIntent']] = Field(None, description='Ordered sub-questions when ONE message carries MORE THAN ONE intent over interrelated subjects; null for single-purpose questions')

as_of class-attribute instance-attribute

as_of: Optional[str] = Field(None, description="The date the question asks about the feature store AT (e.g. 'on 30 June 2023', 'as of 2023-06-30', 'at the end of June 2023'), copied as written. Null when the question is about the current state.")

aquery_optimizer async

aquery_optimizer(sql_query: Optional[str] = None, thread_id: str = 'default', process_id: Optional[str] = None) -> dict

Async entry point — recommended inside Jupyter notebooks and async frameworks.

Parameters:

Name Type Description Default
sql_query Optional[str]

A Teradata SQL statement to optimise, or a follow-up question referencing a previously optimised query in the same thread_id. Can be None when process_id is provided.

None
thread_id str

Conversation thread identifier for multi-turn memory.

'default'
process_id Optional[str]

UUID of a registered tdfs4ds process. When supplied, the SQL and any stored EXPLAIN documentation are fetched from the catalog.

None

Returns:

Type Description
dict

dict with keys answer, best_sql, steps,

dict

filtermanager_applicable, original_analysis, candidates,

dict

comparison, process_info, score_delta, messages.

skill_optimize_query

skill_optimize_query(sql_query: Optional[str] = None, process_id: Optional[str] = None, user_request: str = 'Optimize this Teradata SQL query for performance.', history: Optional[list] = None) -> dict

Analyse and rewrite a Teradata SQL query for better performance.

Either sql_query or process_id must be provided. When process_id is given, the SQL and any existing EXPLAIN documentation are pulled from the tdfs4ds process catalog, avoiding a redundant LLM call.

Parameters:

Name Type Description Default
sql_query Optional[str]

Raw Teradata SELECT statement to optimise.

None
process_id Optional[str]

UUID of a registered tdfs4ds process. When supplied, the SQL view DDL and stored EXPLAIN analysis are fetched from the catalog. If sql_query is also given it takes precedence.

None
user_request str

Optional context sentence describing the optimisation goal (surfaced in the report and fed to the LLM).

'Optimize this Teradata SQL query for performance.'
history Optional[list]

Prior LangGraph messages for multi-turn context.

None

Returns:

Type Description
dict

dict with keys: answer — Structured Markdown optimisation report. best_sql — Recommended SQL (original if already optimal). steps — List of {step, ...} dicts for each pipeline step. filtermanager_applicable — True if a FilterManager loop was recommended. original_analysis — Structured EXPLAIN analysis of the original query. candidates — List of candidate dicts (sql, strategy, analysis). comparison — Plan comparison result. process_info — Process catalog info dict (or None).

Raises:

Type Description
ValueError

If neither sql_query nor process_id is provided.

skill_generate_candidates

skill_generate_candidates(sql_query: str, user_request: str, original_analysis: dict, ddls: dict, lineage_info: dict, history: Optional[list]) -> tuple[list[dict], list[dict], Optional['StrategiesOutput']]

Strategy-based candidate generation with multi-round refinement.

Pipeline
  1. Plan strategies — combinatorial: one strategy per [You] item (sequential), then one per pair (simultaneous), then triplets, etc. No LLM call needed; capped at QUERY_OPTIMIZER_MAX_CANDIDATES.
  2. Execute each strategy — For each strategy sequentially: a. Generate one candidate implementing that strategy. b. EXPLAIN the candidate → extract remaining [You] items. c. If [You] items remain, refine the candidate (up to QUERY_OPTIMIZER_MAX_REFINE_ROUNDS rounds), each round targeting the [You] items from the previous round. d. Early stop the entire pipeline when a strategy achieves user_score = 5/5 (no [You] items remaining).
Returns

candidate_analyses : list[dict] One entry per strategy executed. Each has index, sql, strategy, strategy_description, strategy_targets, rationale, analysis, and rounds (list of per-round dicts). steps : list[dict] Pipeline step records for skill_optimize_query. strategy_plan : StrategiesOutput | None The raw plan returned by the strategy-planning LLM call (None when the query was already optimal and no strategies were generated).

display_optimization_result

display_optimization_result(result: dict) -> None

Render an optimization result dict in a Jupyter notebook cell.

Displays a score comparison widget (before vs. after user/global scores) at the top, then converts the Markdown answer to HTML using the markdown package (with fenced_code, tables, and sane_lists extensions) and renders it inside a styled container via IPython.display.HTML.

Parameters:

Name Type Description Default
result dict

Dict returned by query_optimizer / aquery_optimizer / skill_optimize_query.

required

skill_simplify_query

skill_simplify_query(sql_query: Optional[str] = None, process_id: Optional[str] = None, max_fix_attempts: int = 3) -> dict

Simplify a Teradata SQL query by removing unnecessary nesting.

Applies deterministic passes (comment stripping, identity-wrapper flattening, reserved-word alias fixes) followed by an LLM pass that merges derived-table layers into CTEs and inlines date arithmetic.

The simplified SQL is validated with EXPLAIN; if the score regresses below the original, the deterministic-only version is returned.

Can be used standalone or as a pre-step in skill_optimize_query.

Parameters:

Name Type Description Default
sql_query Optional[str]

Raw Teradata SQL to simplify.

None
process_id Optional[str]

UUID of a registered tdfs4ds process (fetches SQL from catalog).

None
max_fix_attempts int

Max syntax-error repair retries for the LLM output.

3

Returns:

Type Description
dict

dict with keys simplified_sql, original_sql, simplified,

dict

original_score, simplified_score.

simplify_query

simplify_query(sql_query: Optional[str] = None, process_id: Optional[str] = None) -> dict

Synchronous entry point for SQL simplification.

Convenience wrapper around skill_simplify_query for scripts and notebooks. No LangGraph — single-shot operation.

Parameters:

Name Type Description Default
sql_query Optional[str]

Raw Teradata SQL to simplify.

None
process_id Optional[str]

UUID of a registered tdfs4ds process.

None

Returns:

Type Description
dict

dict with keys simplified_sql, original_sql, simplified,

dict

original_score, simplified_score.

intent_classifier

intent_classifier(question: str, intent_model=None, intent_descriptions: dict = None, context_hint: Optional[str] = None)

Classify a user question into one of the available intents.

Parameters:

Name Type Description Default
question str

User question in natural language (French or English).

required
intent_model

Pydantic model for structured output. When None, falls back to the hardwired :class:IntentResult covering all 8 intents.

None
intent_descriptions dict

{intent_name: description} dict used to build the system-prompt intent list. When None, falls back to the hardwired descriptions.

None
context_hint Optional[str]

Optional context about recently mentioned features/datasets (e.g., "Last feature: provider_z_score in entity CLAIM_ID"). Added to the system prompt to help resolve vague follow-up questions.

None

Returns:

Type Description

An instance of intent_model (or :class:IntentResult) with

intent, object_name, and domain fields.

_build_intent_model

_build_intent_model(intents: list)

Build a dynamic Pydantic model for intent classification from a list of intent names.

Uses Union[Literal["A"], Literal["B"], ...] which equals Literal["A", "B", ...] per PEP 586, constructed at runtime via pydantic.create_model.

Parameters:

Name Type Description Default
intents list

List of uppercase intent names (e.g. ["SEARCH", "DEFINITION"]).

required

Returns:

Type Description

A Pydantic BaseModel subclass with an intent field constrained to

the provided values, plus object_name, domain, confidence,

and interpretations optional fields.

list_instruct_models

list_instruct_models() -> pd.DataFrame

List available instruct/chat models from the configured provider.

Returns:

Type Description
DataFrame

DataFrame with columns: MODEL_ID, OWNED_BY (OpenAI-compatible) or

DataFrame

MODEL_ID, PROVIDER, MODALITY (Bedrock).

Raises:

Type Description
ValueError

If the provider is not recognized or not configured.

get_data_domain

get_data_domain() -> pd.DataFrame

List all DATA_DOMAINs available in the feature store.

Returns:

Type Description
DataFrame

DataFrame with columns DATA_DOMAIN and FEATURE_COUNT.

detect_data_domain_for_object

detect_data_domain_for_object(object_name: str, prefer_domain: Optional[str] = None) -> Optional[str]

Return the DATA_DOMAIN that contains object_name as a feature name.

Searches the full feature catalog (all data domains). Falls back to the process catalog (VIEW_NAME) if the feature is not found by name.

Parameters:

Name Type Description Default
object_name str

Feature or view name to locate.

required
prefer_domain Optional[str]

When the object exists in multiple domains, return this one if it is among the matches. Used to prevent silent context switches on ambiguous feature names (e.g. "Claims" appearing in multiple feature stores).

None

Returns:

Type Description
Optional[str]

Matching DATA_DOMAIN string, or None if not found.

Cross-store federation limit (v0.3.1.148): the catalog scanned here is the federated UNION across the primary + read-only stores, but resolution returns a bare DATA_DOMAIN with NO store tag (and _with_domain only switches tdfs4ds.DATA_DOMAIN, not the active store). With DISJOINT stores a domain uniquely identifies its store, so this is correct. If two stores share a domain name, _pick returns the first match (primary rows sort first → primary wins); making resolution store-aware is the documented follow-up.

skill_search(question: str) -> dict

Find features or datasets matching a business need expressed in natural language.

Parameters:

Name Type Description Default
question str

User question describing the business need.

required

Returns:

Type Description
dict

Dict with key matches: list of {name, type, justification}.

skill_definition

skill_definition(question: str, object_name: str, hint_entity_name: Optional[str] = None, hint_table_name: Optional[str] = None, accumulated_context: Optional[dict] = None, _fuzzy_corrected: bool = False) -> dict

Explain what a feature, column, or dataset is in plain business language.

Parameters:

Name Type Description Default
question str

User question.

required
object_name str

Name of the feature, column, or dataset to define.

required
hint_entity_name Optional[str]

Entity name remembered from a previous turn — used to auto-disambiguate when the same feature name exists across entities.

None
hint_table_name Optional[str]

Source table/view remembered from a prior EXPLAIN turn — used to narrow column-level BD lookups to the right table when the column is not a registered feature.

None

Returns:

Type Description
dict

Dict with object_name, explanation, and columns.

skill_usage

skill_usage(question: str, object_name: str, accumulated_context: Optional[dict] = None, entity_name: Optional[str] = None) -> dict

Advise a consumer on how to safely use a feature in their work.

Enumerates ALL datasets that expose the feature (not just one) and emits a paste-ready SELECT snippet for each so the consumer can pick the right view for their dashboard.

Implements fast-path caching: queries accumulated_context_graph first (cache hit → return immediately), falls back to catalog scans (cache miss).

Parameters:

Name Type Description Default
question str

User question about usage (Tableau, Excel, regulatory, etc.).

required
object_name str

Name of the feature or dataset.

required
accumulated_context Optional[dict]

The accumulated_context_graph from state (used for cache).

None
entity_name Optional[str]

Entity name for disambiguation (used in cache lookups).

None

Returns:

Type Description
dict

Dict with object_name, guidance, datasets (list of

dict

{dataset_name, database, dataset_id, select_sql, entity_keys}),

dict

_from_cache (bool), and docs_sources.

skill_freshness

skill_freshness(question: str, object_name: str, hint_entity_name: Optional[str] = None, accumulated_context: Optional[dict] = None, _fuzzy_corrected: bool = False) -> dict

Tell the consumer whether a feature or dataset is up to date and reliable.

Parameters:

Name Type Description Default
question str

User question about freshness / reliability.

required
object_name str

Name of the feature or dataset.

required
hint_entity_name Optional[str]

Entity name remembered from a previous turn — used to auto-disambiguate when the same feature name exists across entities.

None

Returns:

Type Description
dict

Dict with object_name, last_successful_run, days_since_update,

dict

has_recent_failure, and reliability_assessment.

skill_summary

skill_summary(question: str, domain: str = None, object_name: str = None, entity_filter: str = None, accumulated_context: dict = None, _entity_fanned: bool = False) -> dict

Give a high-level summary of available features for a domain or a specific dataset.

When object_name resolves to a registered dataset, the response is scoped to that dataset's feature list and the resolved dataset context is returned in the result so the caller can persist it in agent state for follow-up EXPLAIN turns.

When entity_filter is given (or object_name resolves to an entity type), the feature list is scoped to that single entity — answering "what features belong to X?".

Parameters:

Name Type Description Default
question str

User question.

required
domain str

Therapeutic domain to filter by (optional).

None
object_name str

Dataset, entity, or feature name mentioned by the user (optional).

None
entity_filter str

Entity name to scope the feature list (optional).

None

Returns:

Type Description
dict

Dict with domain, total_features, by_granularity, themes_summary.

skill_lineage

skill_lineage(question: str, object_name: str, hint_view_name: Optional[str] = None, accumulated_context: Optional[dict] = None, entity_name: Optional[str] = None, hint_table_name: Optional[str] = None) -> dict

Return the upstream data dependencies of a feature, object, or column.

Walks the dependency graph starting from the registered process view, and returns a structured list of upstream nodes (tables and views) with their types. Does not require LLM — the graph is deterministic.

When object_name is not a feature/dataset/process view (e.g. a plain documented table, view, or a non-feature column), it falls back to the persisted lineage graph (FS_LINEAGE_GRAPH) to position ANY documented object. A column is first resolved to its owning object (TABLE_NAME) and that object is positioned instead — see _position_object_from_graph.

Implements fast-path caching: queries accumulated_context_graph first (cache hit → return immediately), falls back to expensive DDL scans (cache miss → rebuild and merge results for next turn).

Parameters:

Name Type Description Default
question str

User question (used to determine response language).

required
object_name str

Feature, object (table/view/dataset), or column name.

required
hint_view_name Optional[str]

Pre-resolved view name from a prior turn (skips catalog lookup).

None
accumulated_context Optional[dict]

The accumulated_context_graph from state (used for cache).

None
entity_name Optional[str]

Entity name for disambiguation (used in cache lookups).

None
hint_table_name Optional[str]

Owning object for a column (from a prior EXPLAIN/DEFINITION turn via resolved_column_sources) — positions that object directly.

None

Returns:

Type Description
dict

Dict with object_name, process_view, dependencies (list of

dict

{name, type, depth}), plain_summary (LLM plain-language answer),

dict

_from_cache (bool), and resolved_triplet when resolution succeeded.

skill_explain

skill_explain(question: str, object_name: str, hint_view_name: Optional[str] = None, hint_dataset_features: Optional[list] = None) -> dict

Explain how a feature is calculated by reading its process view DDL.

Fetches the SQL definition of the registered process view and asks the LLM to translate the logic into plain business language — no SQL jargon.

When hint_dataset_features is provided and object_name is empty, explains all features from the current dataset context (up to 10) in a single LLM call.

When object_name contains comma-separated feature names, explains each one.

Parameters:

Name Type Description Default
question str

User question.

required
object_name str

Feature or view name. May be comma-separated for multiple features.

required
hint_view_name Optional[str]

Pre-resolved view name from a prior turn (skips catalog lookup).

None
hint_dataset_features Optional[list]

Feature list from a prior SUMMARY turn on a dataset.

None

Returns:

Type Description
dict

Dict with object_name, process_view, explanation, and resolved_triplet.

synthesize_answer

synthesize_answer(question: str, skill_result: dict, intent: str, resolved_feature_list: Optional[list] = None, accumulated_context: Optional[dict] = None) -> str

Convert structured skill output into a plain-language response.

Parameters:

Name Type Description Default
question str

Original user question.

required
skill_result dict

Dict returned by the skill function.

required
intent str

The classified intent (SEARCH, DEFINITION, etc.).

required
resolved_feature_list Optional[list]

Optional list of feature names from current/prior turns (for group context).

None
accumulated_context Optional[dict]

Optional accumulated context graph with cached metadata.

None

Returns:

Type Description
str

A natural language answer suitable for a non-technical business user.

build_graph

build_graph(skills=None, mcp_enabled: bool = False)

Build and compile the LangGraph StateGraph.

The skill set is loaded from the ca-* SKILL.md files bundled with the package (via :func:tdfs4ds.consumer_agent_skill_catalog). Only skills whose intent is in _INTENT_NODE_MAP are registered as graph nodes.

Parameters:

Name Type Description Default
skills

Optional list of intent names (e.g. ['SEARCH', 'DEFINITION']) to restrict the agent to a subset of skills. When None, all installed consumer-agent skills are included.

None
mcp_enabled bool

When True and tdfs4ds.MCP_SERVER_URL is set, adds an MCP_TOOLS intent node that delegates to the configured MCP server.

False

Returns:

Type Description

A compiled LangGraph with MemorySaver checkpointer for multi-turn support.

Raises:

Type Description
ValueError

When no consumer-agent skills are found in the package.

reset_consumer_agent

reset_consumer_agent()

Clear the graph singleton cache.

Call this after adding or removing consumer-agent SKILL.md files so that the next :func:consumer_agent call picks up the new skill set.

get_embeddings

get_embeddings() -> Embeddings

Return a LangChain Embeddings instance based on the active provider.

Resolution order for each setting: - EMBEDDING_MODEL_PROVIDER -> falls back to INSTRUCT_MODEL_PROVIDER - EMBEDDING_MODEL_API_KEY -> falls back to INSTRUCT_MODEL_API_KEY - EMBEDDING_MODEL_URL -> falls back to INSTRUCT_MODEL_URL - EMBEDDING_MODEL_MODEL -> used as-is (default: text-embedding-3-small)

Injects tdfs4ds config variables into environment so that boto3, Azure, and Google Cloud clients pick up credentials and endpoints automatically.

Returns:

Name Type Description
Embeddings Embeddings

A configured LangChain embedding model.

Raises:

Type Description
ValueError

If the resolved provider is not supported.

list_embedding_models

list_embedding_models(sub_paths: list[str] | None = None) -> 'pd.DataFrame'

List available embedding models from the configured provider.

For LiteLLM setups with multiple TEI backends (e.g. /v1/e5, /v1/code), pass the sub-path names to query each one::

list_embedding_models(sub_paths=['e5', 'code'])

Each sub-path is appended to INSTRUCT_MODEL_URL and queried for /models. Results are merged into a single DataFrame with a SUB_PATH column.

When sub_paths is None, the function derives the sub-path from EMBEDDING_MODEL_URL (if set) or queries INSTRUCT_MODEL_URL directly.

Parameters:

Name Type Description Default
sub_paths list[str] | None

List of LiteLLM route prefixes to query (e.g. ['e5', 'code']).

None

Returns:

Type Description
'pd.DataFrame'

DataFrame with columns: MODEL_ID, OWNED_BY, SUB_PATH (OpenAI-compatible) or

'pd.DataFrame'

MODEL_ID, PROVIDER, MODEL_NAME (Bedrock).

Raises:

Type Description
ValueError

If the provider is not recognized or not configured.

build_vector_index

build_vector_index(force_rebuild: bool = False, progress=None, stores=None)

Build or refresh the three vector-store collections from the business dictionary tables.

Dispatches to the configured backend (tdfs4ds.VECTOR_STORE_BACKEND): 'chroma' (default) or 'teradata'.

On Chroma, each feature store has its own three collections (chroma_collection_name). stores lists the stores to index (database names or descriptors; default: every store in tdfs4ds.read_stores(), the primary first). A store that is not the primary is read through its public FS_V_BUSINESS_DICTIONARY_* views, so read rights are enough, and nothing is written to its database. stores is ignored by the Teradata backend, which indexes the primary only.

progress, when given, is called with one dict per step: store, source, collection (1-based), n_collections, done, total (documents to embed in that collection, None before it is known) and detail. A failing callback never stops the build.

Returns, on Chroma, {'stores': [{'store', 'collections': {source: {'embedded', 'skipped', 'error'}}}]}.

Parameters:

Name Type Description Default
force_rebuild bool

If True, delete existing collections and re-index from scratch. On Chroma this needs no special privileges. On Teradata it destroys and recreates each collection, which requires admin privileges (Collection.destroy() is admin-only) — when the destroy is refused the call falls back to the ordinary refresh path with a warning rather than failing. (Before 0.3.1.167 this flag was a no-op on the Teradata backend.) If False: on Chroma, embed only rows that are missing or changed (same text, metadata and embedding model = skipped); on Teradata, refresh an existing collection with update(data_refresh=True), falling back to destroy + recreate, and create a missing one (since 0.3.1.169; see vector_store_teradata.build_teradata_index).

False

search_vector_index

search_vector_index(query: str, sources: list[str] = ('objects', 'sections', 'columns'), section_names: Optional[List[str]] = None, top_k: int = 10, k: Optional[int] = None) -> pd.DataFrame

Search the requested Chroma collections using similarity search.

Parameters:

Name Type Description Default
query str

Natural language search query.

required
sources list[str]

Which collections to search (subset of 'objects', 'sections', 'columns').

('objects', 'sections', 'columns')
section_names Optional[List[str]]

If provided and 'sections' is in sources, filter by SECTION_NAME.

None
top_k int

Number of results per collection.

10
k Optional[int]

Alias for top_k — accepted because k is the near-universal convention in the surrounding ecosystem (Chroma, FAISS, LangChain retrievers), unlike tdfs4ds's own top_k naming. If both are given and differ, k wins and a warning is logged.

None

Returns:

Type Description
DataFrame

DataFrame with columns: SOURCE, OBJECT_NAME, SECTION_NAME, COLUMN_NAME, TEXT, SCORE.

launch_chatbot

launch_chatbot(title: str = 'Feature Store Assistant', description: str = 'Ask questions about available features, datasets, definitions, data freshness, or usage guidance — in French or English.', port: int = 7860, public_base_url: Optional[str] = None, inline: bool = True, share: bool = False, thread_id: Optional[str] = None) -> gr.Blocks

Launch a Gradio chatbot interface for the consumer agent.

Parameters:

Name Type Description Default
title str

Title displayed at the top of the UI.

'Feature Store Assistant'
description str

Subtitle / description text.

'Ask questions about available features, datasets, definitions, data freshness, or usage guidance — in French or English.'
port int

HTTP port for the Gradio server.

7860
public_base_url Optional[str]

If running behind JupyterHub, the public base URL (e.g. https://dmproject.myddns.me). Enables proxy-aware URLs.

None
inline bool

Whether to display an inline iframe in Jupyter.

True
share bool

Whether to create a public Gradio share link.

False
thread_id Optional[str]

Fixed conversation thread ID. If None, a new UUID is generated per session.

None

Returns:

Type Description
Blocks

The Gradio Blocks demo instance.

launch_chatbot_with_index

launch_chatbot_with_index(port: int = 7860, force_rebuild: bool = False, title: str = None, description: str = None, public_base_url: Optional[str] = None, inline: bool = True, share: bool = False, thread_id: Optional[str] = None) -> gr.Blocks

Build the vector index then launch the Gradio chatbot in one call.

Parameters:

Name Type Description Default
port int

HTTP port for the Gradio server.

7860
force_rebuild bool

If True, wipe and rebuild the Chroma index from scratch. If False (default), only index new rows (incremental).

False
title str

Title displayed at the top of the UI.

None
description str

Subtitle / description text.

None
public_base_url Optional[str]

JupyterHub public base URL for proxy-aware links.

None
inline bool

Whether to display an inline iframe in Jupyter.

True
share bool

Whether to create a public Gradio share link.

False
thread_id Optional[str]

Fixed conversation thread ID (None = new UUID per session).

None

Returns:

Type Description
Blocks

The Gradio Blocks demo instance.

launch_chatbot_app

launch_chatbot_app(port: int = 7860, server_name: str = '0.0.0.0', title: str = 'Feature Store Assistant', description: str = None, inline: bool = False, share: bool = False, thread_id: Optional[str] = None) -> gr.Blocks

Launch the consumer-agent chatbot with a Teradata-styled tabbed interface.

The layout uses a left-oriented tab nav (sidebar look) + a hero header, themed via :data:_TD_CSS (Teradata orange/navy palette). Tabs:

  • 💬 Chatbot — the conversational feature-store assistant (left) plus a right Additional skills pane that lists the plugin skills in TDFS4DS_SKILLS_FOLDER and can import/export a skill's SKILL.md.
  • 🔗 Lineage — interactive pyvis dependency graph of the full persisted lineage (FS_LINEAGE_GRAPH). Click Refresh lineage graph to load.
  • 🧪 Evaluation — generate / import / run evaluation scenarios + report.
  • ⚙️ Parameters — live admin controls:

  • Feature store database — switch the active feature store. The target is validated with tdfs4ds.connect(database=..., create_if_missing=False); a database that does not contain a feature store is rejected (no switch).

  • Vector store — backend (chroma/teradata) + Chroma path, and a Refresh/Rebuild button (build_vector_index(force_rebuild=True)).
  • Instruct model / Embedding model — provider, model, URL, API key, proxy (and embedding dimension), applied to the tdfs4ds globals.

Applying any change that affects the data or the model resets the agent (reset_consumer_agent()), rebuilds the index when needed, rotates the conversation thread, and clears the chat — so the session starts clean.

The existing :func:launch_chatbot / :func:launch_chatbot_with_index are unchanged; this is an additive wrapper.

Returns:

Type Description
Blocks

The Gradio Blocks demo instance.

Submodules