Page actions

React Deep Agents Skills preview

Load detailed instructions only when the agent needs them. A skill index names available capabilities, while skill bodies and references are read on demand.

The native React APIs on this page are experimental, private source-build packages. Run the repository example to use them; they are not an npm installation recipe.

Distinguish the index from evidence of a read

The backend provides skill metadata and tool results. The application renders the index separately from the paths actually inspected, because a requested path does not prove that its contents were read successfully. Some metadata arrives only in saved checkpoints, so the example checks that source before presenting a confirmed index. The native view stays read-only.

The React conversation walkthrough connects this capability to requests, tools, UI state, and saved history.

Start an assessment

Choose Run, type a message and choose Send or press Enter. Mid-size jet at KASE fills this exact draft without sending:

Can a mid-size jet operate out of KASE?

Aviation examples use fixed sample data. Only explicit Send creates the owned thread, lazily, using the native selector da-skills. Opening Docs or Run, changing frontend or mode, navigating browser history, filling suggestions and choosing New conversation do not author a run. Mode navigation and browser history preserve the mounted frame and unsent draft. Reload and New clear the draft and local view.

app.tsx
// eslint-disable-next-line @nx/enforce-module-boundaries -- The isolated consumer copies this internal example layout.
import { ExampleFooter, ExampleLayout } from '../../../../shared/react-example';
import { useCallback, useEffect, useState } from 'react';
import { useAgent } from '@threadplane/react';
import {
  ChatInput,
  MessageList,
  ToolObservation,
  Reasoning,
  Citations,
} from '@threadplane/react/chat';
import { Markdown } from '@threadplane/react/markdown';
import type { MessageRow } from '@threadplane/content/messages';
import type { SkillIndex } from './index-projection';
import type { ReadProjection, SkillRead } from './read-projection';
import { copyData, LIMITS, type Authority } from './authority';
import {
  createConnectedApplication,
  type skillsConnection,
} from './connection';
 
function literal(value: unknown): string {
  try {
    const copied = copyData(value);
    const text =
      typeof copied === 'string'
        ? copied
        : JSON.stringify(copied, null, 2) ?? '';
    return text.length <= LIMITS.fieldText
      ? text
      : 'Observation text unavailable: display limit exceeded.';
  } catch {
    return 'Observation text unavailable.';
  }
}
 
/** Application owns row Markdown snapshots and tool/result association. */
export function renderMessage(
  row: MessageRow,
  authority: Authority = { kind: 'unconfirmed' }
) {
  if (row.role === 'tool') return null;
  const label =
    row.role === 'user'
      ? 'You'
      : row.role === 'assistant'
      ? 'Assistant'
      : 'System';
  return (
    <article
      aria-label={label}
      className={`tp-chat-message tp-chat-message--${row.role}`}
    >
      <p className="tp-chat-message__role">{label}</p>
      {row.role === 'assistant' && row.reasoning && (
        <Reasoning snapshot={row.reasoning} />
      )}
      <Markdown snapshot={row.markdown} />
      {row.toolCalls.map((call) => {
        const error =
          call.status === 'error' ||
          (authority.kind === 'terminal' &&
            authority.rawToolStatuses[call.id] === 'error');
        return (
          <div
            key={call.id}
            className="tool-observation"
            data-call-id={call.id}
          >
            <p>
              {error
                ? 'Tool result: error'
                : `Observed delivery: ${call.status}`}
            </p>
            <ToolObservation
              name={call.name}
              argumentsText={literal(call.args)}
              resultText={
                call.status === 'complete'
                  ? literal(call.result)
                  : call.status === 'error'
                  ? literal(call.error)
                  : undefined
              }
              label={error ? 'Observed tool error' : 'Observed tool delivery'}
            />
          </div>
        );
      })}
      {row.role === 'assistant' && row.message.citations && (
        <Citations citations={row.message.citations} />
      )}
    </article>
  );
}
 
const readLabels: Record<SkillRead['kind'], string> = {
  pending: 'Read pending',
  unknown: 'Read status unknown',
  error: 'Read failed',
  unavailable: 'Read evidence unavailable',
  partial: 'Partially inspected',
  inspected: 'Inspected',
};
const hasReads = (value: ReadProjection): value is readonly SkillRead[] =>
  Array.isArray(value);
export function SkillPanels({
  index,
  reads,
}: {
  index: SkillIndex;
  reads: ReadProjection;
}) {
  return (
    <div className="skill-panels">
      <section aria-label="Skills index">
        <h2>Skills index</h2>
        <p>
          The index shows names, descriptions, virtual instruction paths, and
          optional support annotations. Metadata does not establish that
          instructions were read.
        </p>
        {index.kind === 'ready' ? (
          <>
            <p data-testid="skills-source" data-source={index.source}>
              {index.source === 'checkpoint'
                ? 'Confirmed checkpoint'
                : 'Observed root values'}
            </p>
            {!index.skills.length && <p>The skills index is empty.</p>}
            {index.skills.map((skill) => (
              <article key={skill.path}>
                <h3>{skill.name}</h3>
                <p>{skill.description}</p>
                <code>{skill.path}</code>
                {(skill.license !== undefined ||
                  skill.compatibility !== undefined ||
                  skill.allowed_tools !== undefined ||
                  skill.metadata !== undefined) && (
                  <details>
                    <summary>Skill metadata</summary>
                    {skill.license !== undefined && (
                      <p>License: {skill.license ?? 'unspecified'}</p>
                    )}
                    {skill.compatibility !== undefined && (
                      <p>
                        Compatibility: {skill.compatibility ?? 'unspecified'}
                      </p>
                    )}
                    {skill.allowed_tools !== undefined && (
                      <p>
                        Allowed tools:{' '}
                        {skill.allowed_tools.join(', ') || 'none listed'}
                      </p>
                    )}
                    {skill.metadata && <pre>{literal(skill.metadata)}</pre>}
                  </details>
                )}
              </article>
            ))}
          </>
        ) : (
          <p>
            {index.kind === 'absent'
              ? 'No skills index observed.'
              : index.kind === 'stale'
              ? 'Skills index belongs to an earlier conversation.'
              : 'Skills index unavailable.'}
          </p>
        )}
      </section>
      <section aria-label="Skill read observations">
        <h2>Skill read observations</h2>
        <p>
          Instruction bodies and references are read on demand during a
          response. Inspected describes observed read evidence; it does not
          imply the whole file was read.
        </p>
        {hasReads(reads) ? (
          !reads.length ? (
            <p>No associated skill reads observed.</p>
          ) : (
            reads.map((read) => (
              <article key={read.id} data-read-kind={read.kind}>
                <h3>{read.skillName}</h3>
                <p>
                  Read call: <code>{read.id}</code>
                </p>
                <p>
                  {read.category === 'instruction'
                    ? 'Skill instruction'
                    : 'Skill reference'}
                </p>
                <code>{read.path}</code>
                <p>{readLabels[read.kind]}</p>
                {read.empty && <p>An empty-file reminder was observed.</p>}
                {read.result !== undefined && (
                  <details>
                    <summary>Literal read result</summary>
                    <pre>{read.result}</pre>
                  </details>
                )}
              </article>
            ))
          )
        ) : (
          <p>Read observations unavailable.</p>
        )}
      </section>
    </div>
  );
}
 
export function SkillsDemo({
  connection,
  onReady,
}: {
  connection: ReturnType<typeof skillsConnection>;
  onReady: () => void;
}) {
  const [application] = useState(() => createConnectedApplication(connection));
  const [draft, setDraft] = useState('');
  const snapshot = useAgent(application);
  const renderRow = useCallback(
    (row: MessageRow) => renderMessage(row, snapshot.authority),
    [snapshot.authority]
  );
  useEffect(() => {
    onReady();
  }, [onReady]);
  useEffect(
    () => () => {
      void application.dispose();
    },
    [application]
  );
  useEffect(() => {
    setDraft('');
  }, [snapshot.viewGeneration]);
  const status = snapshot.busy
    ? snapshot.activity === 'confirming'
      ? 'Confirming saved conversation…'
      : snapshot.activity === 'restoring'
      ? 'Restoring conversation…'
      : snapshot.activity === 'creating'
      ? 'Creating conversation…'
      : 'Receiving response…'
    : !snapshot.canSubmit
    ? 'Start a new conversation to continue.'
    : snapshot.outcome === 'success'
    ? 'Response saved.'
    : 'Ready.';
  return (
    <ExampleLayout className="skills-demo">
      <header>
        <div>
          <h1>Deep Agents skills</h1>
        </div>
        <button
          type="button"
          onClick={() => {
            setDraft('');
            void application.newConversation();
          }}
        >
          New conversation
        </button>
      </header>
      <p>
        Inspect progressive disclosure of skill metadata, instructions, and
        reference files. Aviation examples use fixed sample data. Stop cancels
        local delivery; backend work may continue.
      </p>
      <div className="seed-prompts" aria-label="Example prompts">
        <button
          type="button"
          disabled={snapshot.busy || !snapshot.canSubmit}
          onClick={() => {
            const current = application.getSnapshot();
            if (current.canSubmit && !current.busy)
              setDraft('Can a mid-size jet operate out of KASE?');
          }}
        >
          Mid-size jet at KASE
        </button>
      </div>
      <label>
        Saved conversations{' '}
        <select
          aria-label="Saved conversations"
          value={snapshot.threadId ?? ''}
          disabled={snapshot.busy}
          onChange={(event) => {
            if (!event.target.value) return;
            setDraft('');
            void application.selectConversation(event.target.value);
          }}
        >
          <option value="">Choose a saved conversation</option>
          {snapshot.history.map((entry) => (
            <option key={entry.id} value={entry.id}>
              {entry.label}
            </option>
          ))}
        </select>
      </label>
      <div className="skills-workspace">
        <div className="skills-chat">
          <MessageList
            rows={snapshot.rows}
            renderMessage={renderRow}
            label="Conversation"
          />
          <ExampleFooter>
            {snapshot.error && <p role="alert">{snapshot.error}</p>}
            <ChatInput
              key={snapshot.viewGeneration}
              label="Message"
              value={draft}
              onValueChange={setDraft}
              placeholder="Ask about aircraft and runway requirements…"
              hint="Enter to send. Shift+Enter adds a new line."
              busy={snapshot.busy}
              disabled={!snapshot.canSubmit && !snapshot.busy}
              onStop={snapshot.busy ? () => void application.stop() : undefined}
              onSubmit={(text) => {
                const current = application.getSnapshot();
                if (!current.canSubmit || current.busy || !text.trim())
                  return false;
                void application.submit(text);
                return true;
              }}
            />
            <p role="status">{status}</p>
          </ExampleFooter>
        </div>
        <aside className="skills-sidebar" aria-label="Skills sidebar">
          <SkillPanels index={snapshot.index} reads={snapshot.reads} />
        </aside>
      </div>
    </ExampleLayout>
  );
}
connection.ts
import { Client } from '@langchain/langgraph-sdk';
import { createSession } from '@threadplane/langgraph';
// eslint-disable-next-line @nx/enforce-module-boundaries -- Internal bridge is copied by the isolated build.
import type { RuntimeBridgeConfiguration } from '../../../../../libs/cockpit-runtime-bridge/src/index';
import {
  createSkillsApplication,
  type SkillsClient,
  type SkillsSession,
} from './application';
import { copyData, record, text, LIMITS, type Checkpoint } from './authority';
export interface SkillsConnection {
  readonly apiUrl: string;
  readonly headers: Record<string, string>;
}
export function skillsConnection(
  configuration: RuntimeBridgeConfiguration
): SkillsConnection {
  if (
    configuration.status === 'error' ||
    (configuration.status === 'configured' &&
      configuration.target.kind === 'ag-ui')
  )
    throw Error('Runtime configuration failed.');
  const target =
    configuration.status === 'configured' &&
    configuration.target.kind === 'langsmith'
      ? configuration.target
      : null;
  return {
    apiUrl: target?.apiUrl ?? new URL('/api', window.location.origin).href,
    headers: target ? { 'x-api-key': target.apiKey } : {},
  };
}
export function createSkillsClient(input: SkillsConnection): SkillsClient {
  const connection = Object.freeze({
      apiUrl: input.apiUrl,
      headers: Object.freeze({ ...input.headers }),
    }),
    known = new Set<string>();
  const client = new Client({
    apiUrl: connection.apiUrl,
    apiKey: null,
    defaultHeaders: connection.headers,
    callerOptions: { maxRetries: 0 },
  });
  function owned(id: string, signal: AbortSignal) {
    if (!known.has(id) || signal.aborted)
      throw Error('Conversation unavailable.');
  }
  return {
    async createThread(signal) {
      if (signal.aborted) throw Error('Aborted');
      const id = crypto.randomUUID(),
        created = await client.threads.create({
          threadId: id,
          ifExists: 'raise',
          signal,
        });
      if (signal.aborted || created.thread_id !== id)
        throw Error('Conversation creation was not confirmed.');
      known.add(id);
      return id;
    },
    sessionFactory(id) {
      if (!known.has(id)) throw Error('Unknown conversation.');
      const session = createSession({
        assistantId: 'da-skills',
        threadId: id,
        apiUrl: connection.apiUrl,
        clientOptions: { maxRetries: 0, defaultHeaders: connection.headers },
      });
      try {
        const state = session.getSnapshot();
        if (
          ![
            'getSnapshot',
            'subscribe',
            'submit',
            'load',
            'stop',
            'dispose',
          ].every(
            (k) => typeof session[k as keyof typeof session] === 'function'
          ) ||
          ![
            state.messages,
            state.toolCalls,
            state.interrupts,
            state.subgraphs,
          ].every((x) => Array.isArray(x) && x.length === 0)
        )
          throw Error('Rejected session');
        return session as SkillsSession;
      } catch {
        void Promise.resolve(session.dispose()).catch(() => undefined);
        throw Error('Runtime session is unavailable.');
      }
    },
    async readCurrent(id, signal) {
      owned(id, signal);
      const value = await client.threads.getState(id, undefined, { signal });
      owned(id, signal);
      return value;
    },
    async readHistory(id, signal) {
      owned(id, signal);
      const value = await client.threads.getHistory(id, { limit: 1, signal });
      owned(id, signal);
      return value;
    },
    async readCheckpoint(requested, signal) {
      const v = copyData(requested, false);
      if (
        !record(v) ||
        !text(v.thread_id) ||
        v.checkpoint_ns !== '' ||
        !text(v.checkpoint_id) ||
        v.checkpoint_id.length > LIMITS.fieldText ||
        Object.keys(v).some(
          (k) =>
            ![
              'thread_id',
              'checkpoint_ns',
              'checkpoint_id',
              'checkpoint_map',
            ].includes(k)
        ) ||
        (v.checkpoint_map !== undefined &&
          (!record(v.checkpoint_map) ||
            Object.keys(v.checkpoint_map).length !== 1 ||
            v.checkpoint_map[''] !== v.checkpoint_id))
      )
        throw Error('Checkpoint unavailable.');
      const c = v as unknown as Checkpoint;
      owned(c.thread_id, signal);
      const value = await client.threads.getState(
        c.thread_id,
        c as Parameters<typeof client.threads.getState>[1],
        { signal }
      );
      owned(c.thread_id, signal);
      return value;
    },
  };
}
export function createConnectedApplication(connection: SkillsConnection) {
  return createSkillsApplication(createSkillsClient(connection));
}

Inspect the index and actual reads

The index exposes names, descriptions, virtual instruction paths and optional support annotations from root skills_metadata. The local compiled graph exposes metadata in root stream values and saved checkpoints. Observed deployed API values omit private Skills keys while saved checkpoints retain metadata, consistent with declared output-schema filtering. Angular uses the custom event for its live index. React reads native root values and, when the public stream omits metadata, the confirmed saved checkpoint. The custom event does not supply React index authority or confirmed-read proof. Metadata alone does not establish that instructions were read. Both runway-analysis and weather-brief remain index evidence even when only one has associated reads.

Observed root values identifies live index evidence. Confirmed checkpoint requires matching current root state, fresh history head, exact checkpoint and the native transcript/load. Only absent live skills_metadata and skills_load_errors are permitted; present private values and every ordinary root value must agree with the checkpoint. Loaded values must agree fully. Saved checkpoint metadata remains authoritative. This Skills contract makes no inference about Memory visibility.

index-projection.ts
import { copyData, displayUnits, LIMITS, record, text } from './authority';
 
export interface Skill {
  readonly name: string;
  readonly description: string;
  readonly path: string;
  readonly metadata?: Readonly<Record<string, string>>;
  readonly license?: string | null;
  readonly compatibility?: string | null;
  readonly allowed_tools?: readonly string[];
}
export interface IndexInput {
  readonly owner: string;
  readonly generation: string;
  readonly currentOwner: string;
  readonly currentGeneration: string;
  readonly source: 'observed-root' | 'checkpoint';
  readonly values: unknown;
}
export type SkillIndex =
  | {
      readonly kind: 'ready';
      readonly source: IndexInput['source'];
      readonly owner: string;
      readonly generation: string;
      readonly skills: readonly Skill[];
    }
  | { readonly kind: 'absent' | 'unavailable' | 'stale' };
 
/** Literal canonical virtual paths only; never decode or normalize a model path. */
export function skillPath(value: unknown): value is string {
  return (
    text(value) &&
    value.length <= LIMITS.fieldText &&
    value.startsWith('/skills/') &&
    !/[\\\\%?#\u0000-\u0020\u007f]/.test(value) &&
    value
      .slice(1)
      .split('/')
      .every((part) => part.length > 0 && part !== '.' && part !== '..')
  );
}
 
/** Every call replaces the projection. Empty, absent and malformed values cannot
 * revive a previously observed index. Custom event metadata is never a source. */
export function projectIndex(input: IndexInput): SkillIndex {
  try {
    const owned = copyData(input) as IndexInput;
    if (
      !['owner', 'generation', 'currentOwner', 'currentGeneration'].every(
        (k) => {
          const v = owned[k as keyof IndexInput];
          return text(v) && v.length <= LIMITS.fieldText;
        }
      )
    )
      return { kind: 'unavailable' };
    if (
      owned.owner !== owned.currentOwner ||
      owned.generation !== owned.currentGeneration
    )
      return { kind: 'stale' };
    if (
      !['observed-root', 'checkpoint'].includes(owned.source) ||
      !record(owned.values)
    )
      return { kind: 'unavailable' };
    if (!Object.hasOwn(owned.values, 'skills_metadata'))
      return { kind: 'absent' };
    const entries = owned.values.skills_metadata;
    if (!Array.isArray(entries) || entries.length > LIMITS.entries)
      return { kind: 'unavailable' };
    const names = new Set<string>(),
      paths = new Set<string>(),
      strings: string[] = [],
      skills: Skill[] = [];
    for (const v of entries) {
      if (
        !record(v) ||
        !text(v.name) ||
        v.name.length > 64 ||
        !/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(v.name) ||
        !text(v.description) ||
        !skillPath(v.path) ||
        v.path !== '/skills/' + v.name + '/SKILL.md' ||
        names.has(v.name) ||
        paths.has(v.path)
      )
        return { kind: 'unavailable' };
      names.add(v.name);
      paths.add(v.path);
      const skill: Record<string, unknown> = {
        name: v.name,
        description: v.description,
        path: v.path,
      };
      strings.push(v.name, v.description, v.path);
      for (const key of ['license', 'compatibility']) {
        const value = v[key];
        if (value !== undefined) {
          if (value !== null && typeof value !== 'string')
            return { kind: 'unavailable' };
          skill[key] = value;
          if (typeof value === 'string') strings.push(value);
        }
      }
      if (v.metadata !== undefined) {
        if (
          !record(v.metadata) ||
          Object.keys(v.metadata).length > LIMITS.entries
        )
          return { kind: 'unavailable' };
        for (const [key, value] of Object.entries(v.metadata)) {
          if (!text(key) || typeof value !== 'string')
            return { kind: 'unavailable' };
          strings.push(key, value);
        }
        skill.metadata = v.metadata;
      }
      if (v.allowed_tools !== undefined) {
        if (
          !Array.isArray(v.allowed_tools) ||
          v.allowed_tools.length > LIMITS.entries ||
          v.allowed_tools.some((v) => !text(v)) ||
          new Set(v.allowed_tools).size !== v.allowed_tools.length
        )
          return { kind: 'unavailable' };
        strings.push(...v.allowed_tools);
        skill.allowed_tools = v.allowed_tools;
      }
      skills.push(Object.freeze(skill) as unknown as Skill);
    }
    displayUnits(strings);
    return Object.freeze({
      kind: 'ready',
      source: owned.source,
      owner: owned.owner,
      generation: owned.generation,
      skills: Object.freeze(skills),
    });
  } catch {
    return { kind: 'unavailable' };
  }
}
authority.ts
import type { Message, ToolCall } from '@threadplane/core';
 
/** All limits count UTF16 code units, including property keys. */
export const LIMITS = Object.freeze({
  depth: 32,
  nodes: 10000,
  copyText: 4 * 1024 * 1024,
  displayText: 1024 * 1024,
  fieldText: 65536,
  entries: 100,
});
export const record = (v: unknown): v is Record<string, unknown> =>
  !!v && typeof v === 'object' && !Array.isArray(v);
export const text = (v: unknown): v is string =>
  typeof v === 'string' && v.length > 0;
 
/** Bounded capture before recursion or serialization. Never evaluates an accessor.
 * Enumerable keys are counted before the reflective own-key scan; descriptors
 * are inspected individually rather than allocating an unbounded descriptor map. */
export function copyData(value: unknown, allowUndefined = true): unknown {
  let nodes = 0,
    units = 0;
  const parents = new Set<object>();
  const charge = (s: string) => {
    units += s.length;
    if (units > LIMITS.copyText) throw new Error('Data text limit');
  };
  function visit(v: unknown, depth: number): unknown {
    if (++nodes > LIMITS.nodes || depth > LIMITS.depth)
      throw new Error('Data structure limit');
    if (v === null || typeof v === 'boolean') return v;
    if (typeof v === 'string') {
      charge(v);
      return v;
    }
    if (v === undefined && allowUndefined) return undefined;
    if (typeof v === 'number' && Number.isFinite(v)) return v;
    if (typeof v !== 'object' || v === null || parents.has(v))
      throw new Error('Nonplain data');
    const array = Array.isArray(v),
      proto = Object.getPrototypeOf(v);
    if (
      array
        ? proto !== Array.prototype
        : proto !== Object.prototype && proto !== null
    )
      throw new Error('Nonplain prototype');
    const length = array
      ? Object.getOwnPropertyDescriptor(v, 'length')?.value
      : undefined;
    if (
      array &&
      (!Number.isInteger(length) || length > LIMITS.nodes - nodes || length < 0)
    )
      throw new Error('Array limit');
    let enumerable = 0;
    for (const k in v)
      if (Object.hasOwn(v, k) && ++enumerable > LIMITS.nodes - nodes)
        throw new Error('Key limit');
    const keys = Reflect.ownKeys(v);
    if (keys.length > LIMITS.nodes - nodes + (array ? 1 : 0))
      throw new Error('Key limit');
    if (array && keys.length !== length + 1)
      throw new Error('Sparse or decorated array');
    const out: Record<string, unknown> | unknown[] = array
      ? []
      : Object.create(null);
    parents.add(v);
    for (const k of keys) {
      if (typeof k !== 'string') throw new Error('Symbol data');
      if (array && k === 'length') continue;
      if (array && (!/^(0|[1-9][0-9]*)$/.test(k) || Number(k) >= length))
        throw new Error('Decorated array');
      charge(k);
      const d = Object.getOwnPropertyDescriptor(v, k);
      if (!d || !('value' in d) || !d.enumerable)
        throw new Error('Accessor or hidden data');
      Object.defineProperty(out, k, {
        value: visit(d.value, depth + 1),
        enumerable: true,
      });
    }
    parents.delete(v);
    return Object.freeze(out);
  }
  return visit(value, 0);
}
 
/** Stable semantic equality for already-owned bounded plain data. */
export function sameData(a: unknown, b: unknown): boolean {
  if (a === b) return true;
  if (Array.isArray(a) && Array.isArray(b))
    return a.length === b.length && a.every((v, i) => sameData(v, b[i]));
  if (!record(a) || !record(b)) return false;
  const ak = Object.keys(a),
    bk = Object.keys(b);
  return (
    ak.length === bk.length &&
    ak.every((k) => Object.hasOwn(b, k) && sameData(a[k], b[k]))
  );
}
 
export function displayUnits(strings: readonly string[]): number {
  let total = 0;
  for (const s of strings) {
    if (typeof s !== 'string') throw new Error('Unavailable display text');
    if (s.length > LIMITS.fieldText) throw new Error('Display field limit');
    total += s.length;
    if (total > LIMITS.displayText) throw new Error('Display aggregate limit');
  }
  return total;
}
/** Already-owned optional native metadata stays literal and contract-shaped. */
export function validMessageMetadata(m: Record<string, unknown>): boolean {
  if (
    ['name', 'reasoning', 'toolCallId'].some(
      (k) => m[k] !== undefined && typeof m[k] !== 'string'
    )
  )
    return false;
  if (
    m.toolCallIds !== undefined &&
    (!Array.isArray(m.toolCallIds) ||
      m.toolCallIds.some((v) => !text(v)) ||
      new Set(m.toolCallIds).size !== m.toolCallIds.length)
  )
    return false;
  if (
    m.citations !== undefined &&
    (!Array.isArray(m.citations) ||
      m.citations.some(
        (c) =>
          !record(c) ||
          !text(c.id) ||
          typeof c.index !== 'number' ||
          !Number.isFinite(c.index) ||
          ['title', 'url', 'snippet', 'sourceType', 'iconUrl'].some(
            (k) => c[k] !== undefined && typeof c[k] !== 'string'
          ) ||
          (c.publishedAt !== undefined &&
            typeof c.publishedAt !== 'string' &&
            typeof c.publishedAt !== 'number')
      ))
  )
    return false;
  return true;
}
export interface Baseline {
  readonly messages: readonly unknown[];
}
export interface TurnIdentity {
  readonly owner: string;
  readonly generation: string;
  readonly threadId: string;
  readonly humanId: string;
  readonly humanContent: string;
}
export interface Turn extends TurnIdentity {
  readonly baseline: Baseline;
}
export interface Checkpoint {
  readonly thread_id: string;
  readonly checkpoint_ns: '';
  readonly checkpoint_id: string;
  readonly checkpoint_map?: Readonly<Record<string, string>>;
}
export interface NativeSnapshot {
  readonly status: string;
  readonly messages: readonly Message[];
  readonly toolCalls: readonly ToolCall[];
  readonly values?: unknown;
  readonly interrupts: readonly unknown[];
  readonly subgraphs: readonly unknown[];
  readonly error?: unknown;
}
export interface AuthorityInput {
  readonly turn: Turn | undefined;
  readonly owner: string;
  readonly generation: string;
  readonly threadId: string;
  readonly outcome: string;
  /** Current root from the owned raw client, never child values or native synthesis. */
  readonly observedState: unknown;
  /** Fresh raw history from that same client and thread, newest first. */
  readonly history: readonly unknown[];
  /** Exact getState(thread, history[0].checkpoint), not a second current lookup. */
  readonly loadedCheckpoint: unknown;
  readonly snapshot: NativeSnapshot;
  readonly loadedSnapshot: NativeSnapshot;
}
export type Authority =
  | { readonly kind: 'unconfirmed' }
  | {
      readonly kind: 'terminal';
      readonly checkpoint: Checkpoint;
      readonly messages: readonly unknown[];
      readonly values: Readonly<Record<string, unknown>>;
      readonly rawToolStatuses: Readonly<Record<string, 'success' | 'error'>>;
      readonly turn: Turn;
    };
export function captureBaseline(
  input: unknown = { messages: [] }
): Baseline | undefined {
  try {
    const v = copyData(input, false);
    if (!record(v) || !Array.isArray(v.messages)) return undefined;
    return Object.freeze({ messages: v.messages });
  } catch {
    return undefined;
  }
}
export function captureTurn(
  baseline: Baseline | undefined,
  input: TurnIdentity
): Turn | undefined {
  try {
    const b = copyData(baseline, false),
      identity = copyData(input, false);
    if (
      !record(b) ||
      !Array.isArray(b.messages) ||
      !record(identity) ||
      ['owner', 'generation', 'threadId', 'humanId'].some(
        (k) =>
          !text(identity[k]) ||
          (identity[k] as string).length > LIMITS.fieldText
      ) ||
      typeof identity.humanContent !== 'string' ||
      identity.humanContent.length > LIMITS.fieldText ||
      b.messages.some((m) => record(m) && m.id === identity.humanId)
    )
      return undefined;
    return Object.freeze({ ...identity, baseline: b }) as unknown as Turn;
  } catch {
    return undefined;
  }
}
function checkpointSource(
  value: unknown,
  threadId: string
): Checkpoint | undefined {
  if (
    !record(value) ||
    value.thread_id !== threadId ||
    value.checkpoint_ns !== '' ||
    !text(value.checkpoint_id) ||
    value.checkpoint_id.length > LIMITS.fieldText ||
    Object.keys(value).some(
      (k) =>
        ![
          'thread_id',
          'checkpoint_ns',
          'checkpoint_id',
          'checkpoint_map',
        ].includes(k)
    )
  )
    return undefined;
  if (
    value.checkpoint_map !== undefined &&
    (!record(value.checkpoint_map) ||
      Object.keys(value.checkpoint_map).length !== 1 ||
      value.checkpoint_map[''] !== value.checkpoint_id)
  )
    return undefined;
  return value as unknown as Checkpoint;
}
const empty = (v: unknown) =>
  v === undefined || (Array.isArray(v) && v.length === 0);
const clean = (v: Record<string, unknown>) =>
  (v.error === undefined || v.error === null) &&
  empty(v.interrupts) &&
  empty(v.subgraphs) &&
  empty(v.__interrupt__);
 
/** Canonical root semantics independent of native delivery bookkeeping. */
function normalizedRaw(raw: readonly unknown[]):
  | {
      messages: Record<string, unknown>[];
      tools: Record<string, unknown>[];
      statuses: Record<string, 'success' | 'error'>;
    }
  | undefined {
  const messages: Record<string, unknown>[] = [],
    tools = new Map<string, Record<string, unknown>>(),
    ids = new Set<string>(),
    pending = new Set<string>(),
    statuses: Record<string, 'success' | 'error'> = Object.create(null);
  for (const w of raw) {
    if (
      !record(w) ||
      !text(w.id) ||
      ids.has(w.id) ||
      typeof w.content !== 'string' ||
      !clean(w) ||
      !empty(w.invalid_tool_calls) ||
      !['human', 'ai', 'tool'].includes(w.type as string)
    )
      return undefined;
    ids.add(w.id);
    const extra = w.additional_kwargs ?? {};
    if (
      !record(extra) ||
      !empty(extra.tool_calls) ||
      extra.function_call !== undefined
    )
      return undefined;
    const reasoning =
      typeof w.reasoning === 'string'
        ? w.reasoning
        : typeof extra.reasoning_content === 'string'
        ? extra.reasoning_content
        : undefined;
    // Supported citation shape is normalized explicitly; no private runtime imports.
    const source = extra.citations ?? extra.sources;
    let citations: unknown;
    if (Array.isArray(source))
      citations = source.map((s, i) => {
        if (typeof s === 'string')
          return { id: `c${i + 1}`, index: i + 1, url: s };
        const r = record(s) ? s : {},
          out: Record<string, unknown> = {
            id:
              [r.id, r.refId].find((x) => typeof x === 'string') ?? `c${i + 1}`,
            index:
              typeof r.index === 'number' && Number.isFinite(r.index)
                ? r.index
                : i + 1,
          };
        for (const [k, aliases] of Object.entries({
          title: ['title', 'name'],
          url: ['url', 'href', 'source'],
          snippet: ['snippet', 'content', 'excerpt'],
          sourceType: ['sourceType'],
          iconUrl: ['iconUrl'],
        })) {
          const v = aliases.map((a) => r[a]).find((x) => typeof x === 'string');
          if (v !== undefined) out[k] = v;
        }
        if (
          typeof r.publishedAt === 'string' ||
          typeof r.publishedAt === 'number'
        )
          out.publishedAt = r.publishedAt;
        if (record(r.extra)) out.extra = r.extra;
        return out;
      });
    const m: Record<string, unknown> = {
      id: w.id,
      role:
        w.type === 'human' ? 'user' : w.type === 'ai' ? 'assistant' : 'tool',
      content: w.content,
      ...(typeof w.name === 'string' ? { name: w.name } : {}),
    };
    if (reasoning !== undefined) m.reasoning = reasoning;
    if (citations !== undefined) m.citations = citations;
    if (w.type === 'ai') {
      if (pending.size || w.tool_call_id !== undefined) return undefined;
      const calls = w.tool_calls ?? [];
      if (!Array.isArray(calls)) return undefined;
      m.toolCallIds = [];
      for (const c of calls) {
        if (
          !record(c) ||
          !text(c.id) ||
          !text(c.name) ||
          tools.has(c.id) ||
          !Object.hasOwn(c, 'args') ||
          (c.type !== undefined && c.type !== 'tool_call') ||
          Object.keys(c).some(
            (k) => !['id', 'name', 'args', 'type'].includes(k)
          )
        )
          return undefined;
        (m.toolCallIds as string[]).push(c.id);
        tools.set(c.id, {
          id: c.id,
          name: c.name,
          args: c.args,
          status: 'pending',
        });
        pending.add(c.id);
      }
    } else if (w.type === 'tool') {
      const t =
        typeof w.tool_call_id === 'string'
          ? tools.get(w.tool_call_id)
          : undefined;
      if (
        !t ||
        !pending.delete(w.tool_call_id as string) ||
        !['success', 'error'].includes(w.status as string) ||
        (w.name !== t.name &&
          !(
            w.status === 'error' &&
            (w.name === null || w.name === undefined)
          )) ||
        !empty(w.tool_calls)
      )
        return undefined;
      m.toolCallId = w.tool_call_id;
      t.status = 'complete';
      t.result = w.content;
      statuses[w.tool_call_id as string] = w.status as 'success' | 'error';
    } else if (
      pending.size ||
      !empty(w.tool_calls) ||
      w.tool_call_id !== undefined
    )
      return undefined;
    messages.push(m);
  }
  if (
    pending.size ||
    messages[0]?.role !== 'user' ||
    messages.at(-1)?.role !== 'assistant' ||
    !text(messages.at(-1)?.content) ||
    (messages.at(-1)?.toolCallIds as unknown[])?.length
  )
    return undefined;
  return { messages, tools: [...tools.values()], statuses };
}
function nativeSemantic(
  input: NativeSnapshot
):
  | { messages: Record<string, unknown>[]; tools: readonly ToolCall[] }
  | undefined {
  if (
    input.status !== 'idle' ||
    (input.error !== undefined && input.error !== null) ||
    !Array.isArray(input.interrupts) ||
    input.interrupts.length ||
    !Array.isArray(input.subgraphs) ||
    !Array.isArray(input.messages) ||
    !Array.isArray(input.toolCalls)
  )
    return undefined;
  const messages: Record<string, unknown>[] = [],
    ids = new Set<string>();
  for (const m of input.messages) {
    if (
      !record(m) ||
      !text(m.id) ||
      ids.has(m.id) ||
      typeof m.content !== 'string' ||
      !validMessageMetadata(m) ||
      !record(m.delivery) ||
      !text(m.delivery.generation) ||
      m.delivery.phase !== 'complete' ||
      m.delivery.outcome !== 'success' ||
      Object.keys(m).some(
        (k) =>
          ![
            'id',
            'role',
            'content',
            'delivery',
            'reasoning',
            'citations',
            'name',
            'toolCallId',
            'toolCallIds',
          ].includes(k)
      )
    )
      return undefined;
    ids.add(m.id);
    const out: Record<string, unknown> = {
      id: m.id,
      role: m.role,
      content: m.content,
    };
    for (const k of ['name', 'reasoning', 'citations', 'toolCallId'])
      if (m[k as keyof Message] !== undefined) out[k] = m[k as keyof Message];
    if (m.role === 'assistant') {
      if (m.toolCallIds !== undefined && !Array.isArray(m.toolCallIds))
        return undefined;
      out.toolCallIds = m.toolCallIds ?? [];
    } else if (!empty(m.toolCallIds)) return undefined;
    messages.push(out);
  }
  return { messages, tools: input.toolCalls };
}
/** Only contiguous, complete result batches declared by a current assistant may
 * permute. Prior canonical history and all human/assistant boundaries stay strict. */
function matchesRoot(
  raw: ReturnType<typeof normalizedRaw>,
  native: ReturnType<typeof nativeSemantic>,
  prefix: number
): boolean {
  if (
    !raw ||
    !native ||
    raw.messages.length !== native.messages.length ||
    raw.tools.length !== native.tools.length
  )
    return false;
  const catalog = new Map<string, ToolCall>();
  for (const t of native.tools) {
    if (
      !record(t) ||
      !text(t.id) ||
      catalog.has(t.id) ||
      t.status !== 'complete'
    )
      return false;
    catalog.set(t.id, t);
  }
  for (const t of raw.tools)
    if (!sameData(t, catalog.get(t.id as string))) return false;
  for (let i = 0; i < raw.messages.length; i++) {
    const r = raw.messages[i],
      n = native.messages[i];
    if (!sameData(r, n)) return false;
    const callIds = r.role === 'assistant' ? (r.toolCallIds as string[]) : [];
    if (i >= prefix && callIds.length) {
      const batch = raw.messages.slice(i + 1, i + 1 + callIds.length),
        observed = native.messages.slice(i + 1, i + 1 + callIds.length);
      if (
        batch.length !== callIds.length ||
        observed.length !== callIds.length ||
        batch.some((m) => m.role !== 'tool') ||
        observed.some((m) => m.role !== 'tool')
      )
        return false;
      const byId = new Map(observed.map((m) => [m.toolCallId, m]));
      if (
        byId.size !== callIds.length ||
        batch.some(
          (m) =>
            !callIds.includes(m.toolCallId as string) ||
            !sameData(m, byId.get(m.toolCallId))
        )
      )
        return false;
      i += callIds.length;
    }
  }
  return true;
}
 
/** Compare already-owned live values with the exact checkpoint projection.
 * Deployed streams can omit the two private Skills keys. Every observed key
 * still agrees exactly; every ordinary checkpoint key must be observed. */
function matchesLiveValues(
  live: unknown,
  checkpoint: Record<string, unknown>
): boolean {
  if (!record(live)) return false;
  return (
    Object.keys(live).every(
      (key) =>
        Object.hasOwn(checkpoint, key) && sameData(live[key], checkpoint[key])
    ) &&
    Object.keys(checkpoint).every(
      (key) =>
        Object.hasOwn(live, key) ||
        key === 'skills_metadata' ||
        key === 'skills_load_errors'
    )
  );
}
 
/** A failure yields no replacement: callers retain previously confirmed authority.
 * The caller captures its owned client and turn once before asynchronous reads. */
export function captureAuthority(input: unknown): Authority {
  const unavailable: Authority = Object.freeze({ kind: 'unconfirmed' });
  try {
    const captured = copyData(input) as AuthorityInput;
    const turn = captured.turn;
    if (
      !turn ||
      ['owner', 'generation', 'threadId', 'humanId'].some(
        (k) =>
          !text((turn as unknown as Record<string, unknown>)[k]) ||
          ((turn as unknown as Record<string, unknown>)[k] as string).length >
            LIMITS.fieldText
      ) ||
      typeof turn.humanContent !== 'string' ||
      turn.humanContent.length > LIMITS.fieldText ||
      captured.outcome !== 'success' ||
      turn.owner !== captured.owner ||
      turn.generation !== captured.generation ||
      turn.threadId !== captured.threadId ||
      !Array.isArray(turn.baseline?.messages)
    )
      return unavailable;
    const observed = copyData(captured.observedState, false),
      loaded = copyData(captured.loadedCheckpoint, false),
      history = copyData(captured.history, false);
    if (
      !record(observed) ||
      !record(loaded) ||
      !Array.isArray(history) ||
      !history.length ||
      !sameData(observed, loaded) ||
      !sameData(history[0], loaded) ||
      !clean(loaded) ||
      !Array.isArray(loaded.next) ||
      loaded.next.length ||
      !Array.isArray(loaded.tasks) ||
      loaded.tasks.length ||
      !record(loaded.values) ||
      !clean(loaded.values) ||
      !Array.isArray(loaded.values.messages)
    )
      return unavailable;
    const cp = checkpointSource(loaded.checkpoint, captured.threadId);
    if (!cp) return unavailable;
    const checkpointIds = new Set<string>();
    for (const h of history) {
      if (!record(h)) return unavailable;
      const c = checkpointSource(h.checkpoint, captured.threadId);
      if (!c || checkpointIds.has(c.checkpoint_id)) return unavailable;
      checkpointIds.add(c.checkpoint_id);
    }
    const messages = loaded.values.messages,
      prefix = turn.baseline.messages;
    if (!sameData(prefix, messages.slice(0, prefix.length))) return unavailable;
    const human = messages[prefix.length];
    if (
      !record(human) ||
      human.type !== 'human' ||
      human.id !== turn.humanId ||
      human.content !== turn.humanContent ||
      messages.filter((m) => record(m) && m.id === turn.humanId).length !== 1 ||
      messages
        .slice(prefix.length + 1)
        .some((m) => record(m) && m.type === 'human')
    )
      return unavailable;
    const raw = normalizedRaw(messages),
      before = nativeSemantic(captured.snapshot),
      after = nativeSemantic(captured.loadedSnapshot);
    const otherValues: Record<string, unknown> = {};
    for (const k of Object.keys(loaded.values))
      if (k !== 'messages' && k !== '__interrupt__')
        otherValues[k] = loaded.values[k];
    if (
      !raw ||
      !matchesRoot(raw, before, prefix.length) ||
      !matchesRoot(raw, after, prefix.length) ||
      !matchesLiveValues(captured.snapshot.values, otherValues) ||
      !sameData(captured.loadedSnapshot.values, otherValues)
    )
      return unavailable;
    return Object.freeze({
      kind: 'terminal',
      checkpoint: cp,
      messages,
      values: loaded.values,
      rawToolStatuses: Object.freeze(raw.statuses),
      turn,
    });
  } catch {
    return unavailable;
  }
}

Inspected requires an associated raw read_file call with supported arguments and an actual successful tool result. Instruction and reference results remain literal text under Literal read result. Inspection does not claim the whole file was read. Partially inspected, Read failed, Read pending, Read status unknown and Read evidence unavailable distinguish incomplete evidence. A requested path or model prose alone cannot establish successful inspection. The Angular guide retains its requested-path marker behavior.

read-projection.ts
import {
  copyData,
  displayUnits,
  LIMITS,
  record,
  sameData,
  type Authority,
} from './authority';
import { skillPath, type SkillIndex } from './index-projection';
export interface SkillRead {
  readonly id: string;
  readonly skillName: string;
  readonly path: string;
  readonly category: 'instruction' | 'reference';
  readonly kind:
    | 'pending'
    | 'unknown'
    | 'error'
    | 'unavailable'
    | 'partial'
    | 'inspected';
  readonly result?: string;
  /** The literal pinned empty-file reminder was observed; no body is invented. */
  readonly empty?: boolean;
}
const EMPTY = 'System reminder: File exists but has empty contents';
const NO_LINES =
  /^System reminder: no lines were read because `limit` was -?\d+\. The file was not inspected and may have contents; retry with `limit` >= 1 to read it\.$/;
const PARTIAL =
  /\n\n\[Read \d+ lines? \(lines \d+-\d+(?: of \d+ total)?\)\. (?:\d+ lines? remaining|More lines remain) from offset \d+\.\]$/;
 
/** Recognize only the pinned text formatter, without interpreting numbered source
 * text as notices. "Inspected" describes evidence, never an entire-file claim. */
function inspectedResult(
  result: string,
  path: string,
  offset: number
): 'inspected' | 'partial' | undefined {
  if (result === EMPTY) return offset > 0 ? 'partial' : 'inspected';
  let body = result,
    partial = offset > 0;
  const clamp =
    '\n\n[Requested offset ' +
    offset +
    ' is before the start of the file; read from line 1 instead.]';
  if (offset < 0 && body.endsWith(clamp)) body = body.slice(0, -clamp.length);
  const pagination = body.match(PARTIAL);
  if (pagination) {
    partial = true;
    body = body.slice(0, -pagination[0].length);
  }
  const truncation =
    "\n\n[Output was truncated due to size limits. The file content is very large. Consider reformatting the file to make it easier to navigate. For example, if this is JSON, use execute(command='jq . " +
    path +
    "') to pretty-print it with line breaks. For other formats, you can use appropriate formatting tools to split long lines.]";
  if (body.endsWith(truncation)) {
    partial = true;
    body = body.slice(0, -truncation.length);
    // The pinned size cap can leave only its documented warning.
    if (!body) return 'partial';
  }
  let previous = 0,
    continuation = 0;
  for (const row of body.split('\n')) {
    const match = /^ *([1-9][0-9]*)(?:\.([1-9][0-9]*))?  [\s\S]*$/.exec(row);
    if (!match) return undefined;
    const line = Number(match[1]),
      chunk = Number(match[2] ?? 0);
    if (!Number.isSafeInteger(line) || !Number.isSafeInteger(chunk))
      return undefined;
    if (chunk) {
      if (line !== previous || chunk !== continuation + 1) return undefined;
    } else if (previous && line !== previous + 1) return undefined;
    previous = line;
    continuation = chunk;
  }
  return partial ? 'partial' : 'inspected';
}
 
/** Native completion carries no ToolMessage status. Confirmed root raw evidence
 * must match the unique native id, exact arguments and literal result again. */
export type ReadProjection =
  | readonly SkillRead[]
  | { readonly kind: 'unavailable' };
export function projectReads(
  index: SkillIndex,
  tools: unknown,
  authority: Authority
): ReadProjection {
  if (index.kind !== 'ready') return [];
  try {
    const calls = copyData(tools);
    if (!Array.isArray(calls) || calls.length > LIMITS.entries)
      return { kind: 'unavailable' };
    if (
      calls.some(
        (call) =>
          !record(call) ||
          typeof call.id !== 'string' ||
          typeof call.name !== 'string'
      )
    )
      return { kind: 'unavailable' };
    if (
      calls.some(
        (call) =>
          record(call) &&
          call.name === 'read_file' &&
          (!record(call.args) || typeof call.args.file_path !== 'string')
      )
    )
      return { kind: 'unavailable' };
    const ownedAuthority = copyData(authority) as Authority;
    const ids = new Map<string, number>();
    for (const call of calls)
      if (record(call) && typeof call.id === 'string')
        ids.set(call.id, (ids.get(call.id) ?? 0) + 1);
    const output: SkillRead[] = [],
      strings: string[] = [];
    for (const call of calls) {
      if (
        !record(call) ||
        typeof call.id !== 'string' ||
        call.name !== 'read_file' ||
        !record(call.args) ||
        !skillPath(call.args.file_path)
      )
        continue;
      const path = call.args.file_path;
      const skill = index.skills.find((s) =>
        path.startsWith(s.path.slice(0, -'SKILL.md'.length))
      );
      if (!skill) continue;
      // A duplicate call is one unavailable row, never two successful reads.
      if (output.some((r) => r.id === call.id)) continue;
      const result =
        typeof call.result === 'string' &&
        call.result.length <= LIMITS.fieldText
          ? call.result
          : undefined;
      const row = {
        id: call.id,
        skillName: skill.name,
        path,
        category:
          path === skill.path
            ? ('instruction' as const)
            : ('reference' as const),
        ...(result !== undefined ? { result } : {}),
      };
      let kind: SkillRead['kind'] =
        call.status === 'pending' ? 'pending' : 'unknown';
      let empty: boolean | undefined;
      const limit = Object.hasOwn(call.args, 'limit') ? call.args.limit : 100,
        offset = Object.hasOwn(call.args, 'offset') ? call.args.offset : 0;
      if (
        ids.get(call.id) !== 1 ||
        (call.result !== undefined && result === undefined) ||
        !Number.isSafeInteger(limit) ||
        !Number.isSafeInteger(offset)
      )
        kind = 'unavailable';
      else if (ownedAuthority.kind === 'terminal') {
        const aiCalls = ownedAuthority.messages
          .flatMap((m) =>
            record(m) && m.type === 'ai' && Array.isArray(m.tool_calls)
              ? m.tool_calls
              : []
          )
          .filter((c) => record(c) && c.id === call.id);
        const results = ownedAuthority.messages.filter(
          (m) => record(m) && m.type === 'tool' && m.tool_call_id === call.id
        );
        const rawCall = aiCalls[0],
          rawResult = results[0];
        if (
          ownedAuthority.turn.owner !== index.owner ||
          ownedAuthority.turn.generation !== index.generation ||
          aiCalls.length !== 1 ||
          results.length !== 1 ||
          !record(rawCall) ||
          !record(rawResult) ||
          rawCall.name !== call.name ||
          !sameData(rawCall.args, call.args) ||
          rawResult.content !== result ||
          call.status !== 'complete'
        )
          kind = 'unavailable';
        else if (rawResult.status !== ownedAuthority.rawToolStatuses[call.id])
          kind = 'unavailable';
        else if (ownedAuthority.rawToolStatuses[call.id] === 'error')
          kind = 'error';
        else if (ownedAuthority.rawToolStatuses[call.id] === 'success') {
          if (
            !Number.isSafeInteger(limit) ||
            (limit as number) <= 0 ||
            !Number.isSafeInteger(offset) ||
            result === undefined ||
            !result ||
            NO_LINES.test(result)
          )
            kind = 'unavailable';
          else {
            kind =
              inspectedResult(result, path, offset as number) ?? 'unavailable';
            if (kind !== 'unavailable') empty = result === EMPTY;
          }
        }
      }
      strings.push(row.id, row.skillName, path, result ?? '');
      output.push(
        Object.freeze({
          ...row,
          kind,
          ...(empty !== undefined ? { empty } : {}),
        })
      );
    }
    displayUnits(strings);
    return Object.freeze(output);
  } catch {
    return { kind: 'unavailable' };
  }
}

Save, restore and stop

Response saved. requires native success and exact fresh root authority. A resolved tool error can still belong to a saved response while the read remains failed. Unsupported data or uncertain confirmation shows a notice and disables Send until New. Display and raw capture limits bound the aggregate conversation before composing prior and current observations; oversized evidence remains unavailable.

Saved conversations restores only an exact retained local checkpoint and transcript. Choosing a saved conversation performs reads without authoring a run. New conversation clears the active draft and view; it retains locally confirmed entries until reload. Stop cancels local delivery; backend work may continue. There is no automatic retry, replay or Resume. Stale owner or generation results cannot restore an older view.

application.ts
import type {
  AgentSession,
  AgentStatus,
  CompleteOutcome,
  ToolCall,
} from '@threadplane/core';
import {
  createMessageContent,
  type MessageRow,
} from '@threadplane/content/messages';
import {
  captureAuthority,
  captureBaseline,
  captureTurn,
  copyData,
  record,
  sameData,
  LIMITS,
  type Authority,
  type Baseline,
  type Turn,
  type Checkpoint,
  type NativeSnapshot,
} from './authority';
import { projectIndex, type SkillIndex } from './index-projection';
import {
  projectReads,
  type ReadProjection,
  type SkillRead,
} from './read-projection';
export interface SkillsSession extends Omit<AgentSession, 'getSnapshot'> {
  getSnapshot(): NativeSnapshot;
  load(options?: { readonly signal?: AbortSignal }): Promise<void>;
}
export interface SkillsClient {
  createThread(signal: AbortSignal): Promise<string>;
  sessionFactory(id: string): SkillsSession;
  readCurrent(id: string, signal: AbortSignal): Promise<unknown>;
  readHistory(id: string, signal: AbortSignal): Promise<readonly unknown[]>;
  readCheckpoint(checkpoint: Checkpoint, signal: AbortSignal): Promise<unknown>;
}
export interface SkillsSnapshot {
  readonly threadId: string | null;
  readonly rows: readonly MessageRow[];
  readonly toolCalls: readonly ToolCall[];
  readonly index: SkillIndex;
  readonly reads: ReadProjection;
  readonly authority: Authority;
  readonly activity:
    | 'idle'
    | 'creating'
    | 'running'
    | 'confirming'
    | 'restoring';
  readonly busy: boolean;
  readonly canSubmit: boolean;
  readonly outcome: CompleteOutcome | null;
  readonly error: string | null;
  readonly viewGeneration: number;
  readonly history: readonly { id: string; label: string }[];
}
const initial = (
  viewGeneration = 0,
  history: SkillsSnapshot['history'] = []
): SkillsSnapshot => ({
  threadId: null,
  rows: [],
  toolCalls: [],
  index: { kind: 'absent' },
  reads: [],
  authority: { kind: 'unconfirmed' },
  activity: 'idle',
  busy: false,
  canSubmit: true,
  outcome: null,
  error: null,
  viewGeneration,
  history,
});
export function createSkillsApplication(client: SkillsClient) {
  type Terminal = Extract<Authority, { kind: 'terminal' }>;
  type Saved = { authority: Terminal; native: NativeSnapshot; label: string };
  type Owner = {
    id: string;
    key: string;
    generation: string;
    session: SkillsSession;
    content: ReturnType<typeof createMessageContent>;
    baseline: Baseline;
    turn?: Turn;
    nativeGeneration?: string;
    expectedText?: string;
    confirmed?: NativeSnapshot;
    authority?: Terminal;
    release?: () => void;
    closed: boolean;
    unsafe: boolean;
    loading: boolean;
    resolved: Map<string, unknown>;
    completed: Map<string, unknown>;
  };
  let snapshot = initial(),
    owner: Owner | undefined,
    operation: AbortController | undefined,
    disposed = false,
    serial = 0,
    conversationSerial = 0,
    disposal: Promise<void> | undefined;
  const listeners = new Set<() => void>(),
    catalog = new Map<string, Saved>(),
    cleanups = new Set<Promise<void>>();
  const publish = (update: Partial<SkillsSnapshot>) => {
    if (disposed) return;
    snapshot = Object.freeze({ ...snapshot, ...update });
    listeners.forEach((f) => f());
  };
  const history = () => [...catalog].map(([id, s]) => ({ id, label: s.label }));
  function bounded(work: () => void | Promise<void>) {
    let timer: ReturnType<typeof setTimeout>;
    return Promise.race([
      Promise.resolve()
        .then(work)
        .catch(() => undefined),
      new Promise<void>((r) => {
        timer = setTimeout(r, 2000);
      }),
    ]).finally(() => clearTimeout(timer));
  }
  function close(o: Owner) {
    if (o.closed) return Promise.resolve();
    o.closed = true;
    // Each owned resource gets its release attempt even if another cleanup fails.
    try {
      o.release?.();
    } catch {
      /* Continue releasing the session. */
    }
    try {
      o.content.dispose();
    } catch {
      /* Continue releasing the session. */
    }
    const p = bounded(() => o.session.dispose());
    cleanups.add(p);
    void p.finally(() => cleanups.delete(p));
    return p;
  }
  function detach() {
    const o = owner;
    owner = undefined;
    return o ? close(o) : Promise.resolve();
  }
  function block(o?: Owner) {
    if (o) {
      o.unsafe = true;
      catalog.delete(o.id);
    }
    publish({
      canSubmit: false,
      outcome: 'error',
      error:
        'This conversation could not be confirmed. Start a new conversation to continue.',
      history: history(),
    });
  }
  function install(
    o: Owner,
    s: NativeSnapshot,
    authority: Authority,
    source: 'observed-root' | 'checkpoint'
  ) {
    const index = projectIndex({
      owner: o.key,
      generation: o.generation,
      currentOwner: o.key,
      currentGeneration: o.generation,
      source,
      values: s.values,
    });
    const rows = o.content.project({
      status: s.status as AgentStatus,
      messages: s.messages,
      toolCalls: s.toolCalls,
    });
    const isReadRows = (value: ReadProjection): value is readonly SkillRead[] =>
      Array.isArray(value);
    // Validate the full current catalog first so splitting evidence cannot hide
    // duplicate IDs, aggregate limits, or malformed current calls.
    let reads = projectReads(index, s.toolCalls, { kind: 'unconfirmed' });
    if (source === 'checkpoint') {
      reads = projectReads(index, s.toolCalls, authority);
    } else if (authority.kind === 'terminal' && isReadRows(reads)) {
      // A rebound prior authority applies only to its validated raw call IDs.
      // New calls retain pending/unknown until this turn receives fresh authority.
      const priorCalls = s.toolCalls.filter((call) =>
        Object.hasOwn(authority.rawToolStatuses, call.id)
      );
      const priorReads = projectReads(index, priorCalls, authority);
      if (!isReadRows(priorReads)) reads = { kind: 'unavailable' };
      else {
        const confirmed = new Map(priorReads.map((read) => [read.id, read]));
        reads = reads.map((read) =>
          read.kind === 'unavailable' ? read : confirmed.get(read.id) ?? read
        );
      }
    }
    publish({
      rows,
      toolCalls: s.toolCalls,
      index,
      reads,
      authority,
    });
  }
  function read(o: Owner, valid: () => boolean): NativeSnapshot | undefined {
    if (!valid() || o.loading || o.unsafe) return;
    try {
      const source = o.session.getSnapshot(),
        s = copyData(source) as NativeSnapshot;
      if (
        !record(s) ||
        ![s.messages, s.toolCalls, s.interrupts, s.subgraphs].every(
          Array.isArray
        )
      )
        throw Error('Malformed snapshot');
      if (s.subgraphs.length) throw Error('Unsupported child state');
      if (
        o.confirmed &&
        (s.messages.length < o.confirmed.messages.length ||
          o.confirmed.messages.some(
            (m, i) =>
              !sameData(
                { ...m, delivery: undefined },
                { ...s.messages[i], delivery: undefined }
              )
          ) ||
          o.confirmed.toolCalls.some(
            (t) =>
              !sameData(
                t,
                s.toolCalls.find((x) => x.id === t.id)
              )
          ))
      )
        throw Error('Changed prior baseline');
      if (
        o.expectedText !== undefined &&
        s.messages.length > o.baseline.messages.length
      ) {
        const h = s.messages[o.baseline.messages.length];
        if (
          h.role !== 'user' ||
          h.content !== o.expectedText ||
          !h.delivery?.generation ||
          s.messages
            .slice(o.baseline.messages.length + 1)
            .some((m) => m.role === 'user')
        )
          throw Error('Unowned human');
        if (!o.turn) {
          o.turn = captureTurn(o.baseline, {
            owner: o.key,
            generation: o.generation,
            threadId: o.id,
            humanId: h.id,
            humanContent: o.expectedText,
          });
          o.nativeGeneration = h.delivery.generation;
          if (!o.turn) throw Error('Unavailable turn');
        }
        if (
          s.messages
            .slice(o.baseline.messages.length)
            .some((m) => m.delivery?.generation !== o.nativeGeneration)
        )
          throw Error('Foreign generation');
      }
      if (o.turn) {
        const h = s.messages[o.baseline.messages.length];
        if (
          !h ||
          h.id !== o.turn.humanId ||
          h.delivery.generation !== o.nativeGeneration
        )
          throw Error('Foreign generation');
      }
      for (const m of s.messages) {
        const semantic = { ...m, delivery: undefined };
        if (o.completed.has(m.id) && !sameData(o.completed.get(m.id), semantic))
          throw Error('Changed complete message');
        if (m.delivery?.phase === 'complete') o.completed.set(m.id, semantic);
      }
      for (const t of s.toolCalls) {
        if (o.resolved.has(t.id) && !sameData(o.resolved.get(t.id), t))
          throw Error('Changed resolved tool');
        if (t.status === 'complete' || t.status === 'error')
          o.resolved.set(t.id, t);
      }
      if (
        [...o.completed.keys()].some(
          (id) => !s.messages.some((m) => m.id === id)
        ) ||
        [...o.resolved.keys()].some(
          (id) => !s.toolCalls.some((t) => t.id === id)
        )
      )
        throw Error('Missing completed work');
      if (!valid()) return;
      if (o.session.getSnapshot() !== source) throw Error('Changed source');
      // A validated full prior native prefix permits rebinding prior read
      // evidence to this owner. It grants no authority to the current turn.
      const priorTurn =
        o.authority &&
        captureTurn(o.authority.turn.baseline, {
          owner: o.key,
          generation: o.generation,
          threadId: o.id,
          humanId: o.authority.turn.humanId,
          humanContent: o.authority.turn.humanContent,
        });
      const prior: Authority =
        o.authority && priorTurn
          ? { ...o.authority, turn: priorTurn }
          : { kind: 'unconfirmed' };
      install(o, s, prior, 'observed-root');
      return s;
    } catch {
      if (valid()) block(o);
      return;
    }
  }
  function make(id: string): Owner {
    const o: Owner = {
      id,
      key: String(++serial),
      generation: String(++serial),
      session: client.sessionFactory(id),
      content: createMessageContent(),
      baseline: { messages: [] },
      closed: false,
      unsafe: false,
      loading: false,
      resolved: new Map(),
      completed: new Map(),
    };
    o.release = o.session.subscribe(() => {
      const active = operation;
      if (active && !o.loading)
        read(
          o,
          () =>
            !disposed &&
            operation === active &&
            !active.signal.aborted &&
            owner === o &&
            !o.closed
        );
    });
    return o;
  }
  async function confirm(
    o: Owner,
    controller: AbortController,
    live: NativeSnapshot,
    valid: () => boolean,
    retained?: Saved
  ) {
    const observedState = copyData(
      await client.readCurrent(o.id, controller.signal),
      false
    );
    if (!valid()) return;
    const h = copyData(
      await client.readHistory(o.id, controller.signal),
      false
    );
    if (!valid()) return;
    if (!Array.isArray(h) || !record(h[0])) throw Error('Missing history');
    const requested = copyData(h[0].checkpoint, false) as Checkpoint;
    const loadedCheckpoint = copyData(
      await client.readCheckpoint(requested, controller.signal),
      false
    );
    if (!valid()) return;
    o.loading = true;
    await o.session.load({ signal: controller.signal });
    if (!valid()) return;
    const source = o.session.getSnapshot(),
      loaded = copyData(source) as NativeSnapshot;
    if (!Array.isArray(loaded.subgraphs) || loaded.subgraphs.length)
      throw Error('Unsupported child state');
    const authority = captureAuthority({
      turn: o.turn,
      owner: o.key,
      generation: o.generation,
      threadId: o.id,
      outcome: 'success',
      observedState,
      history: h,
      loadedCheckpoint,
      snapshot: retained ? loaded : live,
      loadedSnapshot: loaded,
    });
    if (
      authority.kind !== 'terminal' ||
      (retained &&
        (!sameData(authority.checkpoint, retained.authority.checkpoint) ||
          !sameData(authority.values, retained.authority.values)))
    )
      throw Error('Unconfirmed root');
    if (!valid()) return;
    if (o.session.getSnapshot() !== source) throw Error('Changed publication');
    const baseline = captureBaseline({ messages: authority.messages });
    if (!baseline) throw Error('Missing baseline');
    o.confirmed = loaded;
    o.authority = authority;
    o.baseline = baseline;
    o.loading = false;
    o.turn = undefined;
    o.expectedText = undefined;
    const saved: Saved = {
      authority,
      native: loaded,
      label: catalog.get(o.id)?.label ?? `Conversation ${++conversationSerial}`,
    };
    // Bound the entire page-local catalog, including repeated raw/native text.
    // Oldest entries leave the selectable catalog rather than remaining usable.
    copyData(saved);
    catalog.delete(o.id);
    catalog.set(o.id, saved);
    while (catalog.size > LIMITS.entries) {
      const oldest = catalog.keys().next().value;
      if (oldest !== undefined) catalog.delete(oldest);
    }
    while (true) {
      try {
        copyData([...catalog.values()]);
        break;
      } catch {
        const oldest = catalog.keys().next().value;
        if (oldest === undefined || oldest === o.id) {
          catalog.delete(o.id);
          throw Error('Unavailable catalog budget');
        }
        catalog.delete(oldest);
      }
    }
    install(o, loaded, authority, 'checkpoint');
    if (!valid()) return;
    publish({ canSubmit: true, outcome: 'success', history: history() });
  }
  async function submit(text: string) {
    if (disposed || snapshot.busy || !snapshot.canSubmit || !text.trim())
      return;
    if (text.length > LIMITS.fieldText) {
      block(owner);
      return;
    }
    const controller = new AbortController();
    operation = controller;
    const current = () =>
      !disposed && operation === controller && !controller.signal.aborted;
    publish({
      busy: true,
      canSubmit: false,
      activity: owner ? 'running' : 'creating',
      outcome: null,
      error: null,
    });
    try {
      if (!current()) return;
      if (!owner) {
        const id = await client.createThread(controller.signal);
        if (!current()) return;
        if (typeof id !== 'string' || !id || id.length > LIMITS.fieldText)
          throw Error('Unknown thread');
        const o = make(id);
        if (!current()) {
          void close(o);
          return;
        }
        owner = o;
        publish({ threadId: id, activity: 'running' });
      }
      const o = owner,
        valid = () => current() && owner === o && !o.closed;
      o.generation = String(++serial);
      o.turn = undefined;
      o.nativeGeneration = undefined;
      o.expectedText = text;
      o.completed = new Map();
      o.resolved = new Map();
      const before = read(o, valid);
      if (!valid()) return;
      if (
        !before ||
        o.unsafe ||
        before.messages.length !== o.baseline.messages.length
      )
        throw Error('Unowned baseline');
      const outcome = await o.session.submit(text, {
        signal: controller.signal,
      });
      if (!valid()) return;
      const live = read(o, valid);
      if (!valid()) return;
      const human = live?.messages[o.baseline.messages.length];
      if (
        !live ||
        o.unsafe ||
        outcome !== 'success' ||
        !human ||
        human.role !== 'user' ||
        human.content !== text ||
        !human.delivery?.generation ||
        live.messages
          .slice(o.baseline.messages.length + 1)
          .some((m) => m.role === 'user')
      )
        throw Error('Unconfirmed delivery');
      o.turn = captureTurn(o.baseline, {
        owner: o.key,
        generation: o.generation,
        threadId: o.id,
        humanId: human.id,
        humanContent: text,
      });
      o.nativeGeneration = human.delivery.generation;
      if (
        !o.turn ||
        live.messages
          .slice(o.baseline.messages.length)
          .some((m) => m.delivery.generation !== o.nativeGeneration)
      )
        throw Error('Foreign generation');
      publish({ activity: 'confirming' });
      await confirm(o, controller, live, valid);
    } catch {
      if (current()) block(owner);
    } finally {
      if (current()) {
        operation = undefined;
        publish({ busy: false, activity: 'idle' });
      }
    }
  }
  async function selectConversation(id: string) {
    if (disposed || !catalog.has(id)) return;
    if (operation && snapshot.threadId === id) {
      await stop();
      return;
    }
    const saved = catalog.get(id);
    if (!saved) return;
    if (operation && snapshot.threadId) catalog.delete(snapshot.threadId);
    operation?.abort();
    operation = undefined;
    const cleanup = detach();
    const controller = new AbortController();
    operation = controller;
    const current = () =>
      !disposed && operation === controller && !controller.signal.aborted;
    snapshot = initial(snapshot.viewGeneration + 1, history());
    publish({
      busy: true,
      canSubmit: false,
      activity: 'restoring',
      threadId: id,
    });
    try {
      await cleanup;
      if (!current()) return;
      const o = make(id);
      owner = o;
      o.loading = true;
      o.turn = captureTurn(saved.authority.turn.baseline, {
        ...saved.authority.turn,
        owner: o.key,
        generation: o.generation,
      });
      const valid = () => current() && owner === o && !o.closed;
      await confirm(o, controller, saved.native, valid, saved);
    } catch {
      if (current()) {
        catalog.delete(id);
        block(owner);
      }
    } finally {
      if (current()) {
        operation = undefined;
        publish({ busy: false, activity: 'idle' });
      }
    }
  }
  async function stop() {
    if (disposed || !operation) return;
    operation.abort();
    operation = undefined;
    const o = owner;
    const invalidated = o?.id ?? snapshot.threadId;
    if (invalidated) catalog.delete(invalidated);
    const p = detach();
    publish({
      busy: false,
      canSubmit: false,
      activity: 'idle',
      outcome: 'aborted',
      error: null,
      history: history(),
    });
    await Promise.all([p, bounded(() => o?.session.stop())]);
  }
  async function newConversation() {
    if (disposed) return;
    if (operation && snapshot.threadId) catalog.delete(snapshot.threadId);
    operation?.abort();
    operation = undefined;
    const p = detach();
    snapshot = initial(snapshot.viewGeneration + 1, history());
    publish({});
    await p;
  }
  function dispose() {
    if (disposal) return disposal;
    disposed = true;
    operation?.abort();
    operation = undefined;
    void detach();
    listeners.clear();
    return (disposal = Promise.all([...cleanups]).then(() => undefined));
  }
  return {
    getSnapshot: () => snapshot,
    subscribe: (f: () => void) => {
      if (disposed) return () => undefined;
      listeners.add(f);
      return () => listeners.delete(f);
    },
    submit,
    stop,
    newConversation,
    selectConversation,
    dispose,
  };
}
export type SkillsApplication = ReturnType<typeof createSkillsApplication>;

Shared backend and source build

Skills instructions and references are mounted read-only through the shared adapter; default thread-local notes remain writable. The complete shared Python source includes the graph, adapter, and bundled instruction and reference assets in Code. The graph and adapter are shown here:

graph.py
"""Deep Agents skills capability: SKILL.md progressive disclosure.
 
A skill is a folder with a `SKILL.md` whose YAML frontmatter carries a `name`
and a `description`. `SkillsMiddleware` loads a name, description, and instruction path into the
system prompt — a short metadata index the model can scan — and leaves the body on the
filesystem for the agent to `read_file` when a request actually matches. That
two-stage load is what "progressive disclosure" means: instruction bodies
contribute tokens when needed, and a reference file body is loaded only
when the SKILL.md sends the agent to it. Index scanning still reads the backend.
 
Where the skills live matters. They must be readable through a backend, and this
demo is deployed on a shared public LangGraph deployment, so a host-filesystem
backend is out — `FilesystemBackend` documents itself as inappropriate for
servers, and the same reasoning retired the sandboxes topic. Instead the bundled
skills are seeded into a process-local `InMemoryStore` at import and mounted
read-only at `/skills/` through a `CompositeBackend`; everything else the agent
writes goes to the thread's own `StateBackend`.
 
Visibility: `PrivateStateAttr` excludes Skills keys from declared input/output
schemas. The local compiled graph exposes metadata in root values and saved
checkpoints. The observed deployed API stream omits private Skills keys while
saved checkpoints retain metadata, consistent with output-schema filtering.
Optional load errors can appear when produced, and normal loads can omit them.
`SkillsVisibilityMiddleware` always includes both keys in its custom event,
using an empty-list fallback for load errors;
The custom event is a live index signal, not confirmed-read proof. This Skills
contract makes no inference about Memory.
"""
 
from pathlib import Path
from typing import Any
 
from deepagents import create_deep_agent
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langchain.agents.middleware import AgentMiddleware
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI
from langgraph.config import get_stream_writer
from langgraph.store.memory import InMemoryStore
 
from src.skills_readonly import ReadOnlySkillsBackend
 
# region skills-constants
PROMPTS_DIR = Path(__file__).parent.parent / "prompts"
SKILLS_DIR = Path(__file__).parent.parent / "skills"
 
#: Mount point the agent sees. `SkillsMiddleware` scans one level below it.
SKILLS_ROOT = "/skills/"
 
SKILLS_NAMESPACE = ("cockpit", "deep-agents-skills")
 
#: Custom stream event name the Angular panel listens for.
SKILLS_EVENT = "deep_agents.skills"
# endregion
 
FIELD_ELEVATION_FT = {
    "KSFO": 13,
    "KDEN": 5434,
    "KJFK": 13,
    "KASE": 7820,
    "KLAX": 125,
    "KBOS": 20,
}
 
RUNWAY_LENGTH_FT = {
    "KSFO": 11870,
    "KDEN": 16000,
    "KJFK": 14511,
    "KASE": 8006,
    "KLAX": 12091,
    "KBOS": 10083,
}
 
WEATHER = {
    "KSFO": "Marine layer, 800 ft overcast, visibility 4 SM, wind 280 at 14.",
    "KDEN": "Clear, visibility 10 SM, wind 350 at 22 gusting 31.",
    "KJFK": "Broken 3500 ft, visibility 10 SM, wind 040 at 9.",
    "KASE": "Few 12000 ft, visibility 10 SM, wind 300 at 6, mountain wave advisory.",
    "KLAX": "Clear, visibility 10 SM, wind 260 at 8.",
    "KBOS": "Overcast 1200 ft, visibility 6 SM, wind 120 at 17.",
}
 
 
@tool
def lookup_field_elevation(airport: str) -> str:
    """Return the field elevation in feet for a four-letter ICAO airport code."""
    elevation = FIELD_ELEVATION_FT.get(airport.upper())
    if elevation is None:
        return f"No field elevation on file for {airport.upper()}."
    return f"{airport.upper()} field elevation is {elevation} ft."
 
 
@tool
def lookup_runway_length(airport: str) -> str:
    """Return the longest runway length in feet for a four-letter ICAO airport code."""
    length = RUNWAY_LENGTH_FT.get(airport.upper())
    if length is None:
        return f"No runway data on file for {airport.upper()}."
    return f"{airport.upper()} longest runway is {length} ft."
 
 
@tool
def lookup_weather(airport: str) -> str:
    """Return the current field conditions for a four-letter ICAO airport code."""
    conditions = WEATHER.get(airport.upper())
    if conditions is None:
        return f"No observation on file for {airport.upper()}."
    return f"{airport.upper()}: {conditions}"
 
 
# region seed-store
def _seed_skills_store() -> InMemoryStore:
    """Load the bundled skill folders into a process-local store.
 
    Read once at import through a writable backend. Runtime access is mounted
    through `ReadOnlySkillsBackend`, which denies every mutation entry point.
    """
    store = InMemoryStore()
    backend = StoreBackend(namespace=lambda _runtime: SKILLS_NAMESPACE, store=store)
    for path in sorted(SKILLS_DIR.rglob("*.md")):
        # Paths are stored WITHOUT the mount prefix. `CompositeBackend` strips
        # the route prefix before delegating, so a store seeded at
        # `/skills/runway-analysis/...` would surface as
        # `/skills/skills/runway-analysis/...` to the agent.
        backend.write(f"/{path.relative_to(SKILLS_DIR).as_posix()}", path.read_text())
    return store
 
 
SKILLS_STORE = _seed_skills_store()
# endregion
 
 
# region visibility-middleware
class SkillsVisibilityMiddleware(AgentMiddleware):
    """Republish `skills_metadata` as a `custom` stream event.
 
    Skills keys are excluded from declared input/output schemas. Local compiled
    root values expose metadata; observed deployed API values omit private keys.
    Saved checkpoints remain authoritative. Optional load errors can appear when
    produced and can be omitted on normal loads. This live index event includes
    both keys, with an empty-list fallback for errors; it does not prove a
    confirmed read and makes no claim about Memory visibility.
    """
 
    @property
    def name(self) -> str:
        return "SkillsVisibilityMiddleware"
 
    def _emit(self, state: dict[str, Any]) -> None:
        metadata = state.get("skills_metadata")
        if metadata is None:
            return
        try:
            writer = get_stream_writer()
        except (RuntimeError, KeyError):
            return
        writer(
            {
                "name": SKILLS_EVENT,
                "data": {
                    "skills_metadata": metadata,
                    "skills_load_errors": state.get("skills_load_errors") or [],
                },
            }
        )
 
    def before_model(self, state: dict[str, Any], runtime: Any) -> None:  # noqa: ANN401, ARG002
        self._emit(state)
        return None
 
    def after_agent(self, state: dict[str, Any], runtime: Any) -> None:  # noqa: ANN401, ARG002
        self._emit(state)
        return None
 
 
# endregion
 
 
# region skills-agent
def build_skills_agent():
    """Build the skills agent.
 
    `CompositeBackend` routes by path prefix, longest first. `/skills/` resolves
    to the seeded store; everything else falls through to `StateBackend`, so any
    notes the agent writes stay on the thread and never touch the skill mount.
    """
    return create_deep_agent(
        model=ChatOpenAI(model="gpt-4.1", temperature=0),
        tools=[lookup_field_elevation, lookup_runway_length, lookup_weather],
        system_prompt=(PROMPTS_DIR / "skills.md").read_text(),
        backend=CompositeBackend(
            default=StateBackend(),
            routes={
                SKILLS_ROOT: ReadOnlySkillsBackend(
                    namespace=lambda _runtime: SKILLS_NAMESPACE,
                    store=SKILLS_STORE,
                ),
            },
        ),
        skills=[SKILLS_ROOT],
        middleware=[SkillsVisibilityMiddleware()],
    )
 
 
# endregion
 
 
graph = build_skills_agent()
skills_readonly.py
"""Read-only StoreBackend mount for bundled Skills on the shared deployment."""
 
from deepagents.backends import StoreBackend
from deepagents.backends.protocol import (
    PERMISSION_DENIED,
    DeleteResult,
    EditResult,
    FileUploadResponse,
    WriteResult,
)
 
 
class ReadOnlySkillsBackend(StoreBackend):
    """Preserve StoreBackend reads while denying every mutation entry point.
 
    Seed the store through a regular StoreBackend before mounting this class.
    The async methods are overridden too: StoreBackend's async implementations
    access the store directly rather than delegating to these sync methods.
    """
 
    def write(self, file_path: str, content: str) -> WriteResult:
        return WriteResult(error=PERMISSION_DENIED)
 
    async def awrite(self, file_path: str, content: str) -> WriteResult:
        return self.write(file_path, content)
 
    def edit(
        self, file_path: str, old_string: str, new_string: str, replace_all: bool = False
    ) -> EditResult:
        return EditResult(error=PERMISSION_DENIED)
 
    async def aedit(
        self, file_path: str, old_string: str, new_string: str, replace_all: bool = False
    ) -> EditResult:
        return self.edit(file_path, old_string, new_string, replace_all)
 
    def delete(self, file_path: str) -> DeleteResult:
        return DeleteResult(error=PERMISSION_DENIED)
 
    async def adelete(self, file_path: str) -> DeleteResult:
        return self.delete(file_path)
 
    def upload_files(self, files: list[tuple[str, bytes]]) -> list[FileUploadResponse]:
        return [FileUploadResponse(path=path, error=PERMISSION_DENIED) for path, _ in files]
 
    async def aupload_files(self, files: list[tuple[str, bytes]]) -> list[FileUploadResponse]:
        return self.upload_files(files)
npx nx build cockpit-deep-agents-skills-react
npx nx e2e cockpit-deep-agents-skills-react

Browser verification uses the actual compiled Python graph, installed native SDK and deterministic model. Fixtures, proof endpoints and verification controls are excluded from public Code and the production frontend.

Looking for something specific?