On this page

Survey first, then choose detail๏ƒ

Prerequisite: opening a Rift. Start at rift.space.frame_viewer. The host-level multi-frame view can enumerate frames without selecting one. The frame, conduit, and spell views require a frame name.

Control the amount you read๏ƒ

Use list_* to discover names and IDs, a brief description to decide what matters, then detail or a specific facet for the selected object. For spells, the ladder is describe_spell_brief, describe_spell, describe_spell_detail, and describe_spell_payload. Source, binding, identity, resolution, and research reads let a caller request a particular concern.

The viewer lessons inspect the method surface and show that a fresh Rift can have an empty assigned-frame set. An empty survey is different from a frame-local request that lacks the required target.

Missing is not always absent๏ƒ

A visibility-filtered description may omit a section because it does not exist or because this Rift may not see it. Use the missing-section/visible-surface probes to understand that boundary. They report withheld section names without exposing their hidden payload bodies.

On the facade, frame_name selects the frame. On a view already bound to a frame, an optional frame name can instead be an assertion that it matches. Read the specific signature rather than treating those two surfaces as interchangeable.

The workflow in code๏ƒ

These are the core steps from the saved example. Use its complete linked script for all class definitions and setup.

 1def main() -> None:
 2    nexus = md.Nexus()
 3    system_config = nexus.create_configuration()
 4    system_config.with_rift_creation_enabled(True)
 5    nexus.activate(system_config)
 6
 7    rift_config = nexus.create_rift_configuration()
 8    rift_config.with_space_type("capability")
 9    rift = nexus.create_rift(configuration=rift_config, rift_name="observatory")
10    rift.mark_active()
11
12    viewer = rift.space.frame_viewer
13    assert isinstance(viewer, md.FrameViewer)
14    print("viewer:", viewer.id)
15
16    # THE FACADE'S COMMON READS. A fresh rift has no assigned frames yet,
17    # so these are honest zeros rather than errors - the read surface
18    # works on an empty world.
19    frame_names = viewer.list_frame_names()
20    print("frames visible:", viewer.count_frames(), frame_names)
21    assert isinstance(frame_names, list)
22    assert viewer.count_frames() == len(frame_names)
23
24    # THE VIEWS SPLIT INTO TWO GROUPS, AND THAT SPLIT IS THE LESSON.
25    #
26    # get_view_multiframe() is HOST-SCOPED - it asks about all frames, so
27    # it needs no frame name and works right now.
28    multiframe = viewer.get_view_multiframe()
29    assert isinstance(multiframe, md.ViewMultiFrame)
30    print("view_multiframe:", type(multiframe).__name__, "(host-scoped)")
31
32    # get_view_frame / get_view_conduit / get_view_spell are FRAME-SCOPED.
33    # THERE IS NO DEFAULT FRAME, and since the signature fix that is now
34    # enforced by the signature itself - omitting the name is a TypeError
35    # at the call, not a ValueError from somewhere inside.
36    for accessor in ("get_view_frame", "get_view_conduit", "get_view_spell"):
37        try:
38            getattr(viewer, accessor)()
39            raise AssertionError(f"{accessor} should require a frame name")
40        except TypeError as error:
41            print(f"  {accessor:18s} requires a frame name: {error}")
42
43    # This rift is contracted to no frames, so there is no name to pass -
44    # which is the honest state of a freshly opened rift.
45    assert rift.list_assigned_frame_names() == ()
46    print("assigned frames:", rift.list_assigned_frame_names(),
47          "- nothing to scope a frame-local view to yet")
48
49    # The view TYPES are still inspectable without an instance, which is
50    # how the next two lessons map their surfaces.
51    for view_type in (md.ViewFrame, md.ViewConduit, md.ViewSpell,
52                      md.ViewMultiFrame):
53        assert isinstance(view_type, type)
54    print("four view types exported:", ", ".join(
55        t.__name__ for t in (md.ViewFrame, md.ViewConduit, md.ViewSpell,
56                             md.ViewMultiFrame)))
57
58    # NO CACHED SNAPSHOT. The facade resolves per invocation, so two calls
59    # hand back two view objects rather than one memoized one.
60    assert viewer.get_view_multiframe() is not viewer.get_view_multiframe()
61    print("fresh view per invocation - nothing to go stale")
62
63    # WHAT VIEWS EXIST? Ask, do not assume.
64    available = viewer.describe_available_views()
65    assert isinstance(available, list)
66    print("describe_available_views ->", len(available), "entries")
67
68    # THE AIX SURFACE. The viewer describes its own method surface...
69    surface = viewer.describe_viewer_method_surface()
70    assert isinstance(surface, dict)
71    print("describe_viewer_method_surface ->", len(surface), "keys")
72
73    # ...and onboards an agent in JSON, at runtime, from the object itself.
74    onboarding = viewer.describe_agent_onboarding_json()
75    assert isinstance(onboarding, str)
76    parsed = json.loads(onboarding)
77    print("describe_agent_onboarding_json -> valid JSON,",
78          len(onboarding), "chars")
79    print("  top-level keys:", sorted(parsed)[:6])
80
81    purpose = viewer.describe_viewer_agent_purpose_json()
82    assert isinstance(purpose, str)
83    json.loads(purpose)
84    print("describe_viewer_agent_purpose_json -> valid JSON")
85
86    # clone() hands back an independent facade over the same world.
87    twin = viewer.clone()
88    assert isinstance(twin, md.FrameViewer)
89    assert twin is not viewer
90    assert twin.count_frames() == viewer.count_frames()
91    print("clone: independent object, same reading")
92
93    print()
94    print("a facade with no snapshot - every read is a fresh resolve")
95    print("and the object onboards its own caller instead of assuming docs")

Runnable examples๏ƒ

All advanced examples ยท Level contents ยท Full contents

Canonical page source