Record Locators and Dependency Trees

Every Smarter resource has a record locator, which a manifest returns as status.recordLocator: the lower-cased name of the resource’s Django model, a hyphen, and the row’s hashed id, e.g. llmclient-rMTAwMDAxMwx or pluginmeta-rMTAwMDAyMwx. The web console addresses a resource’s manifest page, where its manifest can be edited, by the same hashed id, so a record locator is enough to build the url of that page, without a database query.

A broker’s dependency_tree() uses this to describe a resource and, recursively, every resource that it uses, each by its record locator, with its owner and the path of its manifest page, so that a console page can draw the tree with a link on each resource. The Architecture tab of the Prompt Engineer’s Workbench draws an LLMClient’s tree this way. Each kind of resource says what it uses in its broker’s references(), the opposite of dependents(), which says what depends on it and keeps a resource that is still in use from being deleted.

from smarter.apps.llmclient.manifest.brokers.llmclient import SAMLLMClientBroker

broker = SAMLLMClientBroker(None, name="stackademy_sql", kind="LLMClient", user_profile=user_profile)
print(broker.dependency_tree().model_dump_json(indent=2))
LLMClient stackademy_sql            /workbench/llm-clients/rMTAwMDAyMgx/manifest/
├── Provider openai                 /provider/providers/rMTAwMDAwNwx/
│   └── Secret openai_api_key       /secret/secrets/rMTAwMDAxMQx/
└── SqlPlugin stackademy_sql        /llm-tools/plugins/rMTAwMDAyMwx/
    ├── Provider openai             /provider/providers/rMTAwMDAwNwx/
    │   └── Secret openai_api_key   /secret/secrets/rMTAwMDAxMQx/
    └── SqlConnection smarter_test_db   /connection/connections/sql-connection/rMTAwMDAwMQx/
        └── Secret smarter_test_user    /secret/secrets/rMTAwMDAxNQx/

A resource that two others use appears under each of them. A resource that the user may not read keeps its kind and record locator, but not its name, its owner, its url, or what it uses in turn.

Record locators, and the web console manifest pages that they lead to.

A record locator identifies one row of a Smarter resource, e.g. llmclient-rMTAwMDAxMwx: the lower-cased name of its Django model class, a hyphen, and the row’s hashed id. A manifest returns it as status.recordLocator. See smarter.lib.django.models.timestamped_model.TimestampedModel.record_locator.

Each kind of resource has a page in the web console that shows its manifest, in the manifest editor, where it can be changed. Most are addressed by the same hashed id, so that a record locator is enough to build the url of the resource’s manifest page, without a database query:

from smarter.lib.manifest.record_locator import console_url

console_url("llmclient-rMTAwMDAxMwx")
# '/workbench/llm-clients/rMTAwMDAxMwx/manifest/'

The exceptions are an api key (smarter.lib.drf.models.SmarterAuthToken), whose record locator ends with its key_id, and an Extension, whose page is addressed by its slug, which is read from the database.

smarter.lib.manifest.record_locator.ConsolePath

Builds the path of a resource’s web console page from the part of its record locator after the prefix.

alias of Callable[[str], str | None]

smarter.lib.manifest.record_locator.by_hashed_id(namespace, name)[source]

A ConsolePath for a page whose url has the resource’s hashed_id.

Parameters:
  • namespace (str) – The url namespace, e.g. GuardrailReverseNames.namespace.

  • name (str) – The url name, e.g. GuardrailReverseNames.detailview.

Returns:

The function.

Return type:

Callable[[str], str | None]

smarter.lib.manifest.record_locator.console_paths()[source]

The web console manifest page of each kind of resource that has one, by record locator prefix.

An LLMClient’s is its manifest page, not the Prompt Engineer’s Workbench, so that every kind’s page is one where its manifest can be edited. An Extension, which has no manifest, has its own page.

The views are imported here, not at module level, because the url modules import the apps’ views, which import the manifest brokers, which import this module.

Returns:

A ConsolePath for each record locator prefix.

Return type:

dict[str, Callable[[str], str | None]]

smarter.lib.manifest.record_locator.console_url(record_locator)[source]

The path of a resource’s manifest page in the web console, from its record locator.

It is a path, not an absolute url, because the web console’s own pages use it. A kind of resource that has no page, e.g. a Prompt, or a page that this platform does not serve, e.g. the Proxy pages while proxies are turned off, has none.

console_url("guardrail-rNQx")
# '/guardrail/guardrails/rNQx/'
Parameters:

record_locator (str | None) – The resource’s record locator, e.g. llmclient-rMTAwMDAxMwx.

Returns:

The path, or None.

Return type:

str | None

smarter.lib.manifest.record_locator.parse_record_locator(record_locator)[source]

Split a record locator into its prefix and the rest, usually a hashed id.

parse_record_locator("llmclient-rMTAwMDAxMwx")
# ('llmclient', 'rMTAwMDAxMwx')

The prefix is everything before the first hyphen, because a model’s class name has none, and the rest may have some, e.g. the key_id of an api key.

Parameters:

record_locator (str) – The record locator.

Returns:

The prefix and the rest.

Return type:

tuple[str, str]

Raises:

ValueError – If the record locator has no prefix, or nothing after it.

smarter.lib.manifest.record_locator.record_locator_prefix(model_class)[source]

The prefix of a model’s record locators: the lower-cased name of its class, e.g. llmclient.

Parameters:

model_class (type) – The Django model class, e.g. smarter.apps.llmclient.models.LLMClient.

Returns:

The prefix, without the hyphen.

Return type:

str

class smarter.lib.manifest.models.SAMDependencyTreeNode(*, kind: str, icon: str, name: str | None = None, owner: str | None = None, recordLocator: str | None = None, url: str | None = None, detailUrl: str | None = None, readable: bool = True, children: List[SAMDependencyTreeNode] = <factory>)[source]

A resource in a dependency tree: the resource, and, recursively, every resource that it uses.

It is the opposite direction of SAMDependency, which lists the resources that depend on a resource. An LLMClient’s tree has its Provider, its plugins, their Connections, and those Connections’ Secrets. See smarter.lib.manifest.broker.AbstractBroker.dependency_tree().

A resource that the user may not read keeps its kind and record locator, so that the tree still shows that something is there, but not its name, owner or urls, or what it uses in turn.

Each readable resource has two urls: url, its manifest page in the web console, where its manifest can be edited, and detailUrl, the api of its detail (its manifest, what it uses and what uses it), which a resource’s detail dialog in the web console shows when its card is chosen.

Example:

{
  "kind": "LLMClient",
  "icon": "artificial-intelligence",
  "name": "stackademy_sql",
  "owner": "Ada Lovelace (ada)",
  "recordLocator": "llmclient-rMTAwMDAxMwx",
  "url": "/workbench/llm-clients/rMTAwMDAxMwx/manifest/",
  "detailUrl": "/dashboard/api/resource/LLMClient/llmclient-rMTAwMDAxMwx/",
  "readable": true,
  "children": [
    {
      "kind": "SqlPlugin",
      "icon": "file-sheet",
      "name": "stackademy_sql",
      "owner": "Ada Lovelace (ada)",
      "recordLocator": "pluginmeta-rMTEx",
      "url": "/llm-tools/plugins/rMTEx/",
      "detailUrl": "/dashboard/api/resource/SqlPlugin/pluginmeta-rMTEx/",
      "readable": true,
      "children": []
    }
  ]
}
model_config = {'arbitrary_types_allowed': True, 'from_attributes': True, 'frozen': True, 'json_schema_serialization_defaults_required': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(context, /)

This function is meant to behave like a BaseModel method to initialize private attributes.

It takes context as an argument since that’s what pydantic-core passes when calling it.

Parameters:
  • self (BaseModel) – The BaseModel instance.

  • context (Any) – The context.

Return type:

None