Skip to main content
What this builds. An offline demo of the <vs-context> wire format produced by str(kb), str(pipeline), str(agent), str(chatbot), plus their granular variants like kb.item(...) and kb.folder(...). You’ll end up with. Printed wire-format blocks for each object type, the unchanged developer-facing repr(), and an inline-composition example showing they drop straight into f-strings and session.send. Agents receive structured object context by interpolating SDK objects directly into session text. The SDK’s __str__ emits \<vs-context> blocks that the Rust engine parser recognizes and resolves to the real object — no new wire field, no new JSON key. What this demonstrates:
  • str(kb), str(pipeline), str(agent), str(chatbot) -> \<vs-context>
  • kb.item(item_id) / kb.folder(folder_id) for granular references
  • Inline use in session.send() and in f-strings
  • repr() stays developer-facing (never the wire format)
Prerequisites for running end-to-end: export VECTORSHIFT_API_KEY=…

and a conversational agent that can consume <vs-context> input

import asyncio

from vectorshift.agent import Agent, AgentType, LLMInfo, MemoryConfig
from vectorshift.chatbot import Chatbot
from vectorshift.events import SessionEventType
from vectorshift.knowledge_base import KnowledgeBase
from vectorshift.pipeline.object import Pipeline


def demo_strings_offline() -> None:
    """Show the wire format for each class without hitting the API."""
    kb = KnowledgeBase(id="kb_ABC", name="Company Docs")
    pipe = Pipeline(id="pl_SUP")
    agent_stub = Agent(
        id="ag_TUT",
        name="Tutor",
        llm_info=LLMInfo(provider="openai", model_id="gpt-4o"),
        agent_type=AgentType.CONVERSATIONAL,
    )
    chatbot = Chatbot(
        id="cb_HELP",
        name="Helper",
        description="Frontline",
        pipeline_id=pipe.id or "",
    )

    print("--- Wire format (vs-context) ---")
    print(f"KB:         {kb}")
    print(f"KB item:    {kb.item('it_42')}")
    print(f"KB folder:  {kb.folder('fld_9')}")
    print(f"Pipeline:   {pipe}")
    print(f"Agent:      {agent_stub}")
    print(f"Chatbot:    {chatbot}")

    print("\n--- Developer-facing repr (unchanged) ---")
    for obj in (kb, pipe, agent_stub, chatbot):
        print(f"  {obj!r}")

    print("\n--- Inline composition ---")
    msg = f"Search {kb} for Q3 revenue and then run {pipe} to build the brief."
    print(msg)


async def demo_session_send(agent_id: str, kb_id: str, kb_name: str) -> None:
    """Illustrate how to reach a live conversational agent with a KB
    reference embedded inline. Call this only when a conversational agent
    and KB exist in your account."""
    agent = Agent.fetch(id=agent_id)
    kb = KnowledgeBase(id=kb_id, name=kb_name)

    async with await agent.create_session() as session:
        print(f"Session: {session.session_id}")
        await session.send(f"Using {kb}, summarize the last quarterly review.")

        async for event in session.listen(
            event_types=[
                SessionEventType.MESSAGE_DELTA,
                SessionEventType.MESSAGE_COMPLETE,
            ]
        ):
            if event.delta:
                print(event.delta, end="", flush=True)
            if event.is_complete:
                print()
                break


def main() -> None:
    demo_strings_offline()

    # Uncomment + fill in real ids to exercise a live session round-trip.
    # asyncio.run(
    #     demo_session_send(
    #         agent_id="ag_CONVO_REAL",
    #         kb_id="kb_REAL",
    #         kb_name="Company Docs",
    #     )
    # )


if __name__ == "__main__":
    main()

Expected output

--- Wire format (vs-context) ---
KB:         <vs-context type="knowledge_base" id="kb_ABC" name="Company Docs"/>
KB item:    <vs-context type="knowledge_base_item" kb_id="kb_ABC" item_id="it_42"/>
KB folder:  <vs-context type="knowledge_base_folder" kb_id="kb_ABC" folder_id="fld_9"/>
Pipeline:   <vs-context type="pipeline" id="pl_SUP"/>
Agent:      <vs-context type="agent" id="ag_TUT" name="Tutor"/>
Chatbot:    <vs-context type="chatbot" id="cb_HELP" name="Helper"/>

--- Developer-facing repr (unchanged) ---
  KnowledgeBase(id='kb_ABC', name='Company Docs')
  Pipeline(id='pl_SUP')
  ...
  Chatbot(id='cb_HELP', name='Helper', ...)

--- Inline composition ---
Search <vs-context type="knowledge_base" id="kb_ABC" name="Company Docs"/> for Q3 revenue and then run <vs-context type="pipeline" id="pl_SUP"/> to build the brief.
The exact attribute set in each <vs-context> tag may vary with SDK version, but the principle is fixed: str(obj) is what goes on the wire, repr(obj) is what your debugger sees. This means dropping an SDK object into an f-string or session.send(...) is the supported way to attach context — no new keyword argument required.
See Session overview for how the engine resolves <vs-context> blocks during a turn.

See also

Template placeholders

The functional-agent equivalent for inputs, outputs, and tools.

Chatbot session

Drive a Chatbot through a Session for multi-turn replies.

Agent reference

Full method surface.