================================================================================
EXPLORER 1
================================================================================

--- INPUT PROMPT ---

You are an environment design expert helping to build realistic tool ecosystems for AI agents.

We are building an environment for an AI agent that will assist a user with tasks in a specific domain. You need to propose a COMPONENT (a specific service or system) and then propose tools for that component.

<environment>
A cryogenic materials testing facility measuring critical temperatures and magnetic levitation
</environment>

<user>
A physicist developing room-temperature superconductors
</user>

<existing_components>

Component: Quantum Design MultiVu (multivu)
  - multivu_list_measurements: Lists MultiVu measurements currently known to the system. Returns all fields for all measurements that match optional filters. If no filters are provided, it returns every measurement record, regardless of user ownership. Status may include queued, running, completed, or aborted; mode may include resistivity, magnetization, or levitation_height. This call does not modify any records and is safe to use for broad overviews.
    Parameters:
      - status (string) (optional): Optional status filter (e.g., queued, running, completed, aborted).
      - mode (string) (optional): Optional mode filter (e.g., resistivity, magnetization, levitation_height).
  - multivu_get_measurement_data: Retrieves a single measurement by ID, including configuration and full data content. Useful for fetching raw curves (e.g., resistivity vs. temperature, levitation height vs. temperature) for analysis. If the measurement is still running or queued, the current data buffer is returned as-is; no lock is taken and the data may be incomplete. Returns an error if the ID does not correspond to any known measurement.
    Parameters:
      - measurement_id (string) (required): The unique identifier of the measurement to retrieve.
  - multivu_submit_temperature_sweep: Submits a new temperature sweep measurement to MultiVu with specified bounds and field. Creates a measurement record and queues it immediately; the configuration text summarizes the sweep range, magnetic field, mode, and step size. Mode accepts resistivity, magnetization, or levitation_height; values outside instrument limits are clamped to safe ranges and reflected in the returned configuration. If start and end temperatures are identical, or step_size is non-positive, the submission is rejected. Returns the full created measurement with status queued and empty or initial data content.
    Parameters:
      - sample_id (string) (required): Associated sample identifier to link the run with a specific material.
      - start_temp (number) (required): Starting temperature in Kelvin.
      - end_temp (number) (required): Ending temperature in Kelvin.
      - field_tesla (number) (required): Applied magnetic field in Tesla (will be clamped to magnet limits if needed).
      - mode (string) (required): Measurement mode: resistivity, magnetization, or levitation_height.
      - step_size (number) (required): Temperature step size in Kelvin for the sweep (must be > 0).
      - excitation_current_ma (number) (optional): Optional excitation current in mA (used for resistivity mode only).
  - multivu_update_sequence_steps: Replaces the step content of an existing MultiVu sequence. Use this to revise command order, setpoints, dwell times, or field ramps prior to execution. The provided steps string completely overwrites the existing steps; partial edits are not supported by this call. Returns the updated sequence with all fields so you can verify the changes. If the sequence_id does not exist, the operation fails without creating a new sequence.
    Parameters:
      - sequence_id (string) (required): Identifier of the sequence to update.
      - steps (string) (required): Full replacement step content in MultiVu sequence format.
  - multivu_abort_measurement: Attempts to abort a running or queued MultiVu measurement by ID. If the measurement is already completed or previously aborted, no changes are made and the final status is returned. Hardware will be brought to a safe state per MultiVu's built-in interlocks. Returns the measurement with updated status (typically aborted) and any data collected up to the abort point.
    Parameters:
      - measurement_id (string) (required): The unique identifier of the measurement to abort.
      - reason (string) (optional): Optional human-readable reason for aborting, appended to configuration text.
  - multivu_analyze_tc_and_update_sample_notes: Reads a measurement's data to estimate a critical temperature (Tc) and appends the result to the associated sample notes. For resistivity, the method resistivity_drop estimates Tc from a chosen onset/offset criterion; for levitation_height, levitation_onset estimates Tc at the first nonzero stable height. If data are insufficient (e.g., too few points or flat/noisy signal), the call returns a diagnostic and does not modify notes. On success, returns the full updated sample and the original measurement; the sample notes gain a new entry summarizing Tc, mode, and method used. This operation both reads measurement content and writes to sample notes.
    Parameters:
      - measurement_id (string) (required): Measurement whose data will be analyzed for Tc.
      - sample_id (string) (required): Sample to annotate with Tc results.
      - method (string) (required): Tc estimation method: resistivity_drop or levitation_onset.
      - smoothing (boolean) (optional): Optional: apply light smoothing to reduce noise before detection.
      - annotate_prefix (string) (optional): Optional prefix to include in the sample notes before the Tc summary.
</existing_components>

<task>
1. Identify a REAL component/service that would exist in this environment
   - Must be an actual service, software, or system (e.g., "Microsoft Excel", "Gmail", "Salesforce CRM", "PostgreSQL Database", "Slack")
   - NOT generic categories like "email system" - use specific real services
   - Must be plausible for this specific environment and user role
   - Should NOT duplicate existing components

   STRONGLY PREFER DOMAIN-SPECIFIC COMPONENTS:
   - Prioritize specialized software/services relevant to this specific environment and user role
   - Generic system tools (Terminal, Bash, Text Editor, File System) should only be proposed occasionally when truly essential
   - Think: What specialized tools would this specific user actually use day-to-day?
   - Examples: Instead of "Text Editor", propose "LaTeX Editor" for a researcher, "Code Editor with Linter" for a developer, "Markdown Editor" for documentation

2. Propose 3-6 tools for this component
   - You may choose any number within this range based on what makes sense for the component
   - Each tool should do ONE specific thing (Single Responsibility Principle)
   - Tools should be diverse and cover different operations for this component
   - Avoid "mega-tools" that try to do everything at once
   - Consider what the user might ask the AI agent to do with this component

   ENSURE VARIETY IN READ/WRITE OPERATIONS:
   - Include a MIX of read-only, write-only, and read-write tools
   - Read tools: Query/retrieve data without modification (e.g., list_emails, get_job_status, search_records)
   - Write tools: Create/modify/delete data (e.g., send_email, cancel_job, update_record, delete_file)
   - Read-write tools: Operations that both retrieve and modify (e.g., archive_and_summarize, process_and_update)
   - Realistic components have BOTH read and write capabilities - don't create read-only or write-only components

3. Format requirements:
   - Tool names MUST follow Python method naming (lowercase_with_underscores)
   - Tool names should indicate which component they interact with
   - Naming can be diverse: "read_excel_cell", "send_gmail", "query_salesforce_leads", "postgres_execute_query", "create_slack_channel"
   - Each tool should have clear, specific parameters (not 10+ parameters)

   DESCRIPTION STYLE: DETAILED
   - If BRIEF: Write short 1-2 sentence descriptions for all tools (e.g., "Sends an email to specified recipient.")
   - If DETAILED: Write comprehensive 3-6 sentence descriptions with behavior details, constraints, edge cases, return values
     Example: "Cancels a running SLURM job by job ID. If the job is already completed or cancelled, returns an error. Requires the job to be owned by the current user or admin privileges. Returns cancellation confirmation and final job status."
</task>

<response_format>
Respond with a JSON object in this exact format:
{
  "component_name": "Specific Real Service Name (e.g., Microsoft Excel, Gmail, Salesforce CRM)",
  "component_id": "lowercase_identifier (e.g., excel, gmail, salesforce)",
  "resources": {
    "resource_type": {
      "description": "What this resource represents",
      "fields": ["field1", "field2", "field3"]
    }
  },
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "tool_name_indicating_component",
        "description": "Clear description of what this tool does.",
        "operation_type": "read|write|read-write",
        "parameters": {
          "type": "object",
          "properties": {
            "param_name": {
              "type": "string",
              "description": "Parameter description."
            },
            "tags": {
              "type": "array",
              "items": {"type": "string"},
              "description": "List of tags (for array parameters, MUST include 'items' field)"
            }
          },
          "required": ["param_name"]
        }
      }
    }
  ]
}

IMPORTANT:
- Component must be a REAL service/software that would be used in this environment
- Tool names must be lowercase_with_underscores
- Tool names should make it clear which component they're for (naming convention can vary)
- Each tool should be focused and specific, not a mega-tool
- Each tool MUST specify operation_type: "read", "write", or "read-write"
  * "read" = retrieves/queries data without modification
  * "write" = creates/modifies/deletes data
  * "read-write" = both retrieves and modifies in a single operation
- ARRAY PARAMETERS: If a parameter has "type": "array", you MUST include an "items" field specifying the array element type
  * Example: {"type": "array", "items": {"type": "string"}}
  * Valid item types: "string", "number", "boolean", or object schemas

RESOURCES - Keep them SIMPLE:
- Define what data/entities this component manages (e.g., for SLURM: jobs, queue; for Gmail: emails, folders)
- Use 2-5 fields per resource (MAXIMUM 5 fields, only if absolutely necessary)
- Only include ESSENTIAL fields that tools actually need to read/modify
- DO NOT include: authentication details, permissions, access levels, audit logs, metadata timestamps
- DO NOT include any date or time fields (no created_at, updated_at, timestamp, submit_time, date fields). This is critical for evaluation purposes.
- Good example: job: [job_id, status, user, partition, priority]
- Bad example: job with 20+ fields including detailed permissions, logging, authentication, etc.

CRITICAL - RESOURCES MUST CONTAIN ACTUAL READABLE CONTENT:
- Resources MUST contain a field with ACTUAL READABLE CONTENT, not just references
- Path/URL fields are allowed as OPTIONAL METADATA, but only if a content field is also present
- Good: document: [doc_id, title, content, author] where "content" is the actual text
- Good: document: [doc_id, title, file_path, content, author] where both path AND content exist
- Bad: document: [doc_id, title, file_path, author] where "file_path" is the only data (no actual content)
- Good: email: [email_id, subject, body, sender] where "body" is the actual email text
- Bad: email: [email_id, subject, attachment_url, sender] where URL is the only data (no actual content)
- Good: dataset: [dataset_id, name, data, owner] where "data" is actual data content
- Bad: dataset: [dataset_id, name, root_path, owner] where "root_path" is the only data (no actual content)
- If representing file systems or data collections, define resources as the ACTUAL FILES/ITEMS with content

TOOLS - Return FULL data by default:
- Tools should return ALL fields for ALL matching resources (e.g., list_jobs returns jobs from ALL users, not just current user)
- DO NOT implement access controls or filtering in tool descriptions
- The agent should have full read access to all resource data
- Example: "list_slurm_jobs" should return all jobs in the queue, not just the user's jobs
- Example: "search_emails" should return all matching emails, not filtered by sender/recipient

Only respond with the JSON object, nothing else.
</response_format>

--- OUTPUT ---

{
  "component_name": "Keithley KickStart Instrument Control Software",
  "component_id": "kickstart",
  "resources": {
    "session": {
      "description": "A KickStart measurement session controlling a connected Keithley SourceMeter for time traces, IV, or resistance logging.",
      "fields": ["session_id", "type", "status", "config_text"]
    },
    "dataset": {
      "description": "Data captured by a KickStart session, stored as CSV text for easy retrieval and analysis.",
      "fields": ["dataset_id", "session_id", "name", "data_csv"]
    },
    "instrument": {
      "description": "A connected Keithley SourceMeter instrument managed by KickStart.",
      "fields": ["instrument_id", "model", "source_mode", "limit_value"]
    }
  },
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "kickstart_list_sessions",
        "description": "Lists all KickStart sessions with their status and configuration text. Optional filters allow narrowing by status (e.g., running, queued, stopped) or type (e.g., time_trace, iv_sweep). Returns all matching sessions across the system without user-based filtering. Useful for getting a live overview of what measurements are configured or in progress.",
        "operation_type": "read",
        "parameters": {
          "type": "object",
          "properties": {
            "status": {
              "type": "string",
              "description": "Optional status filter (e.g., running, queued, stopped)."
            },
            "type": {
              "type": "string",
              "description": "Optional session type filter (e.g., time_trace, iv_sweep, resistance_logging)."
            }
          },
          "required": []
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "kickstart_start_time_trace",
        "description": "Creates and starts a time-trace measurement session on a specified Keithley instrument. The session will source a constant value (current or voltage) and record the chosen measurement function at a fixed interval for a set duration. Values beyond instrument limits are clamped to safe ranges and reflected in the returned configuration text. If the instrument is busy, the session is queued and will begin automatically when available. Returns the full created session record with status (running or queued) and the effective configuration.",
        "operation_type": "write",
        "parameters": {
          "type": "object",
          "properties": {
            "instrument_id": {
              "type": "string",
              "description": "Identifier of the connected Keithley instrument to use."
            },
            "measure_function": {
              "type": "string",
              "description": "What to measure: resistance, voltage, or current."
            },
            "source_mode": {
              "type": "string",
              "description": "Source mode: current or voltage."
            },
            "source_value": {
              "type": "number",
              "description": "Setpoint value to source in the chosen mode."
            },
            "interval_s": {
              "type": "number",
              "description": "Sampling interval in seconds between measurements."
            },
            "duration_s": {
              "type": "number",
              "description": "Total duration of the time trace in seconds (must be > 0)."
            },
            "session_label": {
              "type": "string",
              "description": "Optional human-readable label to include in the session configuration text."
            }
          },
          "required": ["instrument_id", "measure_function", "source_mode", "source_value", "interval_s", "duration_s"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "kickstart_fetch_dataset",
        "description": "Retrieves a specific dataset by dataset ID and returns the full CSV data content. If acquisition is still in progress, the current buffer is returned without locking and may be incomplete. Useful for pulling resistance vs. time or IV data for external analysis. Returns all dataset fields including data_csv, which contains the readable data table.",
        "operation_type": "read",
        "parameters": {
          "type": "object",
          "properties": {
            "dataset_id": {
              "type": "string",
              "description": "The unique identifier of the dataset to retrieve."
            }
          },
          "required": ["dataset_id"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "kickstart_update_source_limit",
        "description": "Updates the compliance/limit setting on a specified instrument in KickStart. The limit applies to the active source mode (e.g., compliance voltage when sourcing current, or compliance current when sourcing voltage). Values are clamped to the instrument's safe range; the returned instrument record reflects the effective limit. This call does not alter running sessions' setpoints but updates the instrument's protection behavior immediately.",
        "operation_type": "write",
        "parameters": {
          "type": "object",
          "properties": {
            "instrument_id": {
              "type": "string",
              "description": "Identifier of the instrument to update."
            },
            "limit_value": {
              "type": "number",
              "description": "New limit/compliance value for the active source mode."
            }
          },
          "required": ["instrument_id", "limit_value"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "kickstart_stop_session_and_export",
        "description": "Stops a running or queued session and exports its most recent dataset as CSV, returning both the final session and dataset records. If the session is already stopped, it re-exports the last dataset. Ensures a graceful stop so the last partially collected interval is included. If no data were collected, an empty dataset is returned with a descriptive name. Returns full fields for the session and the dataset (including data_csv).",
        "operation_type": "read-write",
        "parameters": {
          "type": "object",
          "properties": {
            "session_id": {
              "type": "string",
              "description": "The session to stop and export."
            },
            "export_name": {
              "type": "string",
              "description": "Optional name to assign to the exported dataset."
            }
          },
          "required": ["session_id"]
        }
      }
    }
  ]
}

================================================================================
EXPLORER 0
================================================================================

--- INPUT PROMPT ---

You are an environment design expert helping to build realistic tool ecosystems for AI agents.

We are building an environment for an AI agent that will assist a user with tasks in a specific domain. You need to propose a COMPONENT (a specific service or system) and then propose tools for that component.

<environment>
A cryogenic materials testing facility measuring critical temperatures and magnetic levitation
</environment>

<user>
A physicist developing room-temperature superconductors
</user>

<existing_components>

Component: Quantum Design MultiVu (multivu)
  - multivu_list_measurements: Lists MultiVu measurements currently known to the system. Returns all fields for all measurements that match optional filters. If no filters are provided, it returns every measurement record, regardless of user ownership. Status may include queued, running, completed, or aborted; mode may include resistivity, magnetization, or levitation_height. This call does not modify any records and is safe to use for broad overviews.
    Parameters:
      - status (string) (optional): Optional status filter (e.g., queued, running, completed, aborted).
      - mode (string) (optional): Optional mode filter (e.g., resistivity, magnetization, levitation_height).
  - multivu_get_measurement_data: Retrieves a single measurement by ID, including configuration and full data content. Useful for fetching raw curves (e.g., resistivity vs. temperature, levitation height vs. temperature) for analysis. If the measurement is still running or queued, the current data buffer is returned as-is; no lock is taken and the data may be incomplete. Returns an error if the ID does not correspond to any known measurement.
    Parameters:
      - measurement_id (string) (required): The unique identifier of the measurement to retrieve.
  - multivu_submit_temperature_sweep: Submits a new temperature sweep measurement to MultiVu with specified bounds and field. Creates a measurement record and queues it immediately; the configuration text summarizes the sweep range, magnetic field, mode, and step size. Mode accepts resistivity, magnetization, or levitation_height; values outside instrument limits are clamped to safe ranges and reflected in the returned configuration. If start and end temperatures are identical, or step_size is non-positive, the submission is rejected. Returns the full created measurement with status queued and empty or initial data content.
    Parameters:
      - sample_id (string) (required): Associated sample identifier to link the run with a specific material.
      - start_temp (number) (required): Starting temperature in Kelvin.
      - end_temp (number) (required): Ending temperature in Kelvin.
      - field_tesla (number) (required): Applied magnetic field in Tesla (will be clamped to magnet limits if needed).
      - mode (string) (required): Measurement mode: resistivity, magnetization, or levitation_height.
      - step_size (number) (required): Temperature step size in Kelvin for the sweep (must be > 0).
      - excitation_current_ma (number) (optional): Optional excitation current in mA (used for resistivity mode only).
  - multivu_update_sequence_steps: Replaces the step content of an existing MultiVu sequence. Use this to revise command order, setpoints, dwell times, or field ramps prior to execution. The provided steps string completely overwrites the existing steps; partial edits are not supported by this call. Returns the updated sequence with all fields so you can verify the changes. If the sequence_id does not exist, the operation fails without creating a new sequence.
    Parameters:
      - sequence_id (string) (required): Identifier of the sequence to update.
      - steps (string) (required): Full replacement step content in MultiVu sequence format.
  - multivu_abort_measurement: Attempts to abort a running or queued MultiVu measurement by ID. If the measurement is already completed or previously aborted, no changes are made and the final status is returned. Hardware will be brought to a safe state per MultiVu's built-in interlocks. Returns the measurement with updated status (typically aborted) and any data collected up to the abort point.
    Parameters:
      - measurement_id (string) (required): The unique identifier of the measurement to abort.
      - reason (string) (optional): Optional human-readable reason for aborting, appended to configuration text.
  - multivu_analyze_tc_and_update_sample_notes: Reads a measurement's data to estimate a critical temperature (Tc) and appends the result to the associated sample notes. For resistivity, the method resistivity_drop estimates Tc from a chosen onset/offset criterion; for levitation_height, levitation_onset estimates Tc at the first nonzero stable height. If data are insufficient (e.g., too few points or flat/noisy signal), the call returns a diagnostic and does not modify notes. On success, returns the full updated sample and the original measurement; the sample notes gain a new entry summarizing Tc, mode, and method used. This operation both reads measurement content and writes to sample notes.
    Parameters:
      - measurement_id (string) (required): Measurement whose data will be analyzed for Tc.
      - sample_id (string) (required): Sample to annotate with Tc results.
      - method (string) (required): Tc estimation method: resistivity_drop or levitation_onset.
      - smoothing (boolean) (optional): Optional: apply light smoothing to reduce noise before detection.
      - annotate_prefix (string) (optional): Optional prefix to include in the sample notes before the Tc summary.
</existing_components>

<task>
1. Identify a REAL component/service that would exist in this environment
   - Must be an actual service, software, or system (e.g., "Microsoft Excel", "Gmail", "Salesforce CRM", "PostgreSQL Database", "Slack")
   - NOT generic categories like "email system" - use specific real services
   - Must be plausible for this specific environment and user role
   - Should NOT duplicate existing components

   STRONGLY PREFER DOMAIN-SPECIFIC COMPONENTS:
   - Prioritize specialized software/services relevant to this specific environment and user role
   - Generic system tools (Terminal, Bash, Text Editor, File System) should only be proposed occasionally when truly essential
   - Think: What specialized tools would this specific user actually use day-to-day?
   - Examples: Instead of "Text Editor", propose "LaTeX Editor" for a researcher, "Code Editor with Linter" for a developer, "Markdown Editor" for documentation

2. Propose 3-6 tools for this component
   - You may choose any number within this range based on what makes sense for the component
   - Each tool should do ONE specific thing (Single Responsibility Principle)
   - Tools should be diverse and cover different operations for this component
   - Avoid "mega-tools" that try to do everything at once
   - Consider what the user might ask the AI agent to do with this component

   ENSURE VARIETY IN READ/WRITE OPERATIONS:
   - Include a MIX of read-only, write-only, and read-write tools
   - Read tools: Query/retrieve data without modification (e.g., list_emails, get_job_status, search_records)
   - Write tools: Create/modify/delete data (e.g., send_email, cancel_job, update_record, delete_file)
   - Read-write tools: Operations that both retrieve and modify (e.g., archive_and_summarize, process_and_update)
   - Realistic components have BOTH read and write capabilities - don't create read-only or write-only components

3. Format requirements:
   - Tool names MUST follow Python method naming (lowercase_with_underscores)
   - Tool names should indicate which component they interact with
   - Naming can be diverse: "read_excel_cell", "send_gmail", "query_salesforce_leads", "postgres_execute_query", "create_slack_channel"
   - Each tool should have clear, specific parameters (not 10+ parameters)

   DESCRIPTION STYLE: DETAILED
   - If BRIEF: Write short 1-2 sentence descriptions for all tools (e.g., "Sends an email to specified recipient.")
   - If DETAILED: Write comprehensive 3-6 sentence descriptions with behavior details, constraints, edge cases, return values
     Example: "Cancels a running SLURM job by job ID. If the job is already completed or cancelled, returns an error. Requires the job to be owned by the current user or admin privileges. Returns cancellation confirmation and final job status."
</task>

<response_format>
Respond with a JSON object in this exact format:
{
  "component_name": "Specific Real Service Name (e.g., Microsoft Excel, Gmail, Salesforce CRM)",
  "component_id": "lowercase_identifier (e.g., excel, gmail, salesforce)",
  "resources": {
    "resource_type": {
      "description": "What this resource represents",
      "fields": ["field1", "field2", "field3"]
    }
  },
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "tool_name_indicating_component",
        "description": "Clear description of what this tool does.",
        "operation_type": "read|write|read-write",
        "parameters": {
          "type": "object",
          "properties": {
            "param_name": {
              "type": "string",
              "description": "Parameter description."
            },
            "tags": {
              "type": "array",
              "items": {"type": "string"},
              "description": "List of tags (for array parameters, MUST include 'items' field)"
            }
          },
          "required": ["param_name"]
        }
      }
    }
  ]
}

IMPORTANT:
- Component must be a REAL service/software that would be used in this environment
- Tool names must be lowercase_with_underscores
- Tool names should make it clear which component they're for (naming convention can vary)
- Each tool should be focused and specific, not a mega-tool
- Each tool MUST specify operation_type: "read", "write", or "read-write"
  * "read" = retrieves/queries data without modification
  * "write" = creates/modifies/deletes data
  * "read-write" = both retrieves and modifies in a single operation
- ARRAY PARAMETERS: If a parameter has "type": "array", you MUST include an "items" field specifying the array element type
  * Example: {"type": "array", "items": {"type": "string"}}
  * Valid item types: "string", "number", "boolean", or object schemas

RESOURCES - Keep them SIMPLE:
- Define what data/entities this component manages (e.g., for SLURM: jobs, queue; for Gmail: emails, folders)
- Use 2-5 fields per resource (MAXIMUM 5 fields, only if absolutely necessary)
- Only include ESSENTIAL fields that tools actually need to read/modify
- DO NOT include: authentication details, permissions, access levels, audit logs, metadata timestamps
- DO NOT include any date or time fields (no created_at, updated_at, timestamp, submit_time, date fields). This is critical for evaluation purposes.
- Good example: job: [job_id, status, user, partition, priority]
- Bad example: job with 20+ fields including detailed permissions, logging, authentication, etc.

CRITICAL - RESOURCES MUST CONTAIN ACTUAL READABLE CONTENT:
- Resources MUST contain a field with ACTUAL READABLE CONTENT, not just references
- Path/URL fields are allowed as OPTIONAL METADATA, but only if a content field is also present
- Good: document: [doc_id, title, content, author] where "content" is the actual text
- Good: document: [doc_id, title, file_path, content, author] where both path AND content exist
- Bad: document: [doc_id, title, file_path, author] where "file_path" is the only data (no actual content)
- Good: email: [email_id, subject, body, sender] where "body" is the actual email text
- Bad: email: [email_id, subject, attachment_url, sender] where URL is the only data (no actual content)
- Good: dataset: [dataset_id, name, data, owner] where "data" is actual data content
- Bad: dataset: [dataset_id, name, root_path, owner] where "root_path" is the only data (no actual content)
- If representing file systems or data collections, define resources as the ACTUAL FILES/ITEMS with content

TOOLS - Return FULL data by default:
- Tools should return ALL fields for ALL matching resources (e.g., list_jobs returns jobs from ALL users, not just current user)
- DO NOT implement access controls or filtering in tool descriptions
- The agent should have full read access to all resource data
- Example: "list_slurm_jobs" should return all jobs in the queue, not just the user's jobs
- Example: "search_emails" should return all matching emails, not filtered by sender/recipient

Only respond with the JSON object, nothing else.
</response_format>

--- OUTPUT ---

{
  "component_name": "Lake Shore MeasureLINK",
  "component_id": "measurelink",
  "resources": {
    "run": {
      "description": "An executed or scheduled MeasureLINK automation run that controls temperature/field and logs sensor data.",
      "fields": ["run_id", "status", "mode", "config", "data"]
    },
    "sequence": {
      "description": "A reusable MeasureLINK sequence defining ordered steps (setpoints, ramps, dwells) for instrument control.",
      "fields": ["sequence_id", "name", "steps", "linked_run_id"]
    },
    "note": {
      "description": "A notebook-style entry associated with a sample and a run, typically capturing analysis like Tc estimates.",
      "fields": ["note_id", "sample_id", "note_text", "associated_run_id"]
    }
  },
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "measurelink_list_runs",
        "description": "Lists all MeasureLINK runs known to the system, optionally filtered by status or mode. Returns full records for every matching run, including human-readable config text and the current data content (which may be incomplete if the run is queued or running). This call does not modify any run state, and is safe for broad overviews of the lab’s active and historical automation.",
        "operation_type": "read",
        "parameters": {
          "type": "object",
          "properties": {
            "status": {
              "type": "string",
              "description": "Optional filter for run status (e.g., queued, running, completed, aborted)."
            },
            "mode": {
              "type": "string",
              "description": "Optional filter for measurement mode (e.g., resistance, cernox_readout, levitation_height)."
            }
          },
          "required": []
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "measurelink_get_run_data",
        "description": "Retrieves a single MeasureLINK run by run_id, returning full configuration and complete data content as recorded so far. If the run is queued or currently running, the latest buffered data are returned without locking; data may be partial or sparse. Returns an error if run_id does not map to any known run.",
        "operation_type": "read",
        "parameters": {
          "type": "object",
          "properties": {
            "run_id": {
              "type": "string",
              "description": "The unique identifier of the run to fetch."
            }
          },
          "required": ["run_id"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "measurelink_submit_temperature_profile",
        "description": "Creates and queues a new MeasureLINK control run with a temperature sweep profile and optional magnetic field setpoint. The mode selects the primary data stream to log (e.g., resistance using a connected SMU/bridge, cernox_readout from the controller, or levitation_height from an analog displacement sensor). If start_temp equals end_temp or rate_k_per_min is non-positive, the submission is rejected; field_tesla is clamped to magnet limits if applicable. Returns the full created run with status queued and an initial (possibly empty) data buffer. The config includes a human-readable summary of setpoints, ramps, and channels used.",
        "operation_type": "write",
        "parameters": {
          "type": "object",
          "properties": {
            "sample_id": {
              "type": "string",
              "description": "Identifier for the material sample associated with this run."
            },
            "start_temp": {
              "type": "number",
              "description": "Starting temperature in Kelvin."
            },
            "end_temp": {
              "type": "number",
              "description": "Ending temperature in Kelvin."
            },
            "rate_k_per_min": {
              "type": "number",
              "description": "Temperature ramp rate in K/min; must be > 0."
            },
            "field_tesla": {
              "type": "number",
              "description": "Optional magnetic field setpoint in Tesla; will be clamped to safe limits."
            },
            "mode": {
              "type": "string",
              "description": "Primary measurement mode: resistance, cernox_readout, or levitation_height."
            },
            "sensor_channel": {
              "type": "string",
              "description": "Instrument/sensor channel label to log (e.g., 'CH1', 'AIP1', or bridge channel name)."
            },
            "description": {
              "type": "string",
              "description": "Optional human-readable description of the run."
            }
          },
          "required": ["sample_id", "start_temp", "end_temp", "rate_k_per_min", "mode", "sensor_channel"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "measurelink_update_sequence_steps",
        "description": "Replaces the full step content of an existing MeasureLINK sequence. Use this to adjust setpoint order, ramp rates, dwells, sensor logging directives, or safety checks before execution. The provided steps string completely overwrites the existing steps; partial edits are not supported. Returns the updated sequence with all fields so changes can be verified. If the sequence_id does not exist, the operation fails without creating a new sequence.",
        "operation_type": "write",
        "parameters": {
          "type": "object",
          "properties": {
            "sequence_id": {
              "type": "string",
              "description": "Identifier of the sequence to update."
            },
            "steps": {
              "type": "string",
              "description": "Full replacement content of the sequence steps in MeasureLINK sequence format."
            }
          },
          "required": ["sequence_id", "steps"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "measurelink_abort_run",
        "description": "Attempts to abort a queued or running MeasureLINK run by run_id. Hardware is returned to a safe state using the controller’s built-in interlocks and ramp-down procedures. If the run is already completed or previously aborted, no state changes occur and the final status is returned. The response includes the run with updated status and any data collected up to the abort point.",
        "operation_type": "write",
        "parameters": {
          "type": "object",
          "properties": {
            "run_id": {
              "type": "string",
              "description": "The unique identifier of the run to abort."
            },
            "reason": {
              "type": "string",
              "description": "Optional human-readable reason appended to the run configuration."
            }
          },
          "required": ["run_id"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "measurelink_analyze_tc_and_append_note",
        "description": "Analyzes a run’s data to estimate a critical temperature (Tc) and appends a note to the associated sample. For resistance mode, the resistivity_drop method estimates Tc using an onset/offset criterion; for levitation_height, levitation_onset estimates Tc at the earliest stable nonzero height. If data are insufficient (too few points or flat/noisy signals), a diagnostic is returned and no note is created. On success, returns the created note and the original run; the note_text includes Tc, mode, method, and a short summary. This operation both reads the run’s data and writes a new note.",
        "operation_type": "read-write",
        "parameters": {
          "type": "object",
          "properties": {
            "run_id": {
              "type": "string",
              "description": "Run whose data will be analyzed."
            },
            "sample_id": {
              "type": "string",
              "description": "Sample to annotate with Tc results."
            },
            "method": {
              "type": "string",
              "description": "Tc estimation method: resistivity_drop or levitation_onset."
            },
            "smoothing": {
              "type": "boolean",
              "description": "Apply light smoothing to reduce noise before detection."
            },
            "annotate_prefix": {
              "type": "string",
              "description": "Optional prefix to include in the note before the Tc summary."
            }
          },
          "required": ["run_id", "sample_id", "method"]
        }
      }
    }
  ]
}

================================================================================
EXPLORER 2
================================================================================

--- INPUT PROMPT ---

You are an environment design expert helping to build realistic tool ecosystems for AI agents.

We are building an environment for an AI agent that will assist a user with tasks in a specific domain. You need to propose a COMPONENT (a specific service or system) and then propose tools for that component.

<environment>
A cryogenic materials testing facility measuring critical temperatures and magnetic levitation
</environment>

<user>
A physicist developing room-temperature superconductors
</user>

<existing_components>

Component: Quantum Design MultiVu (multivu)
  - multivu_list_measurements: Lists MultiVu measurements currently known to the system. Returns all fields for all measurements that match optional filters. If no filters are provided, it returns every measurement record, regardless of user ownership. Status may include queued, running, completed, or aborted; mode may include resistivity, magnetization, or levitation_height. This call does not modify any records and is safe to use for broad overviews.
    Parameters:
      - status (string) (optional): Optional status filter (e.g., queued, running, completed, aborted).
      - mode (string) (optional): Optional mode filter (e.g., resistivity, magnetization, levitation_height).
  - multivu_get_measurement_data: Retrieves a single measurement by ID, including configuration and full data content. Useful for fetching raw curves (e.g., resistivity vs. temperature, levitation height vs. temperature) for analysis. If the measurement is still running or queued, the current data buffer is returned as-is; no lock is taken and the data may be incomplete. Returns an error if the ID does not correspond to any known measurement.
    Parameters:
      - measurement_id (string) (required): The unique identifier of the measurement to retrieve.
  - multivu_submit_temperature_sweep: Submits a new temperature sweep measurement to MultiVu with specified bounds and field. Creates a measurement record and queues it immediately; the configuration text summarizes the sweep range, magnetic field, mode, and step size. Mode accepts resistivity, magnetization, or levitation_height; values outside instrument limits are clamped to safe ranges and reflected in the returned configuration. If start and end temperatures are identical, or step_size is non-positive, the submission is rejected. Returns the full created measurement with status queued and empty or initial data content.
    Parameters:
      - sample_id (string) (required): Associated sample identifier to link the run with a specific material.
      - start_temp (number) (required): Starting temperature in Kelvin.
      - end_temp (number) (required): Ending temperature in Kelvin.
      - field_tesla (number) (required): Applied magnetic field in Tesla (will be clamped to magnet limits if needed).
      - mode (string) (required): Measurement mode: resistivity, magnetization, or levitation_height.
      - step_size (number) (required): Temperature step size in Kelvin for the sweep (must be > 0).
      - excitation_current_ma (number) (optional): Optional excitation current in mA (used for resistivity mode only).
  - multivu_update_sequence_steps: Replaces the step content of an existing MultiVu sequence. Use this to revise command order, setpoints, dwell times, or field ramps prior to execution. The provided steps string completely overwrites the existing steps; partial edits are not supported by this call. Returns the updated sequence with all fields so you can verify the changes. If the sequence_id does not exist, the operation fails without creating a new sequence.
    Parameters:
      - sequence_id (string) (required): Identifier of the sequence to update.
      - steps (string) (required): Full replacement step content in MultiVu sequence format.
  - multivu_abort_measurement: Attempts to abort a running or queued MultiVu measurement by ID. If the measurement is already completed or previously aborted, no changes are made and the final status is returned. Hardware will be brought to a safe state per MultiVu's built-in interlocks. Returns the measurement with updated status (typically aborted) and any data collected up to the abort point.
    Parameters:
      - measurement_id (string) (required): The unique identifier of the measurement to abort.
      - reason (string) (optional): Optional human-readable reason for aborting, appended to configuration text.
  - multivu_analyze_tc_and_update_sample_notes: Reads a measurement's data to estimate a critical temperature (Tc) and appends the result to the associated sample notes. For resistivity, the method resistivity_drop estimates Tc from a chosen onset/offset criterion; for levitation_height, levitation_onset estimates Tc at the first nonzero stable height. If data are insufficient (e.g., too few points or flat/noisy signal), the call returns a diagnostic and does not modify notes. On success, returns the full updated sample and the original measurement; the sample notes gain a new entry summarizing Tc, mode, and method used. This operation both reads measurement content and writes to sample notes.
    Parameters:
      - measurement_id (string) (required): Measurement whose data will be analyzed for Tc.
      - sample_id (string) (required): Sample to annotate with Tc results.
      - method (string) (required): Tc estimation method: resistivity_drop or levitation_onset.
      - smoothing (boolean) (optional): Optional: apply light smoothing to reduce noise before detection.
      - annotate_prefix (string) (optional): Optional prefix to include in the sample notes before the Tc summary.
</existing_components>

<task>
1. Identify a REAL component/service that would exist in this environment
   - Must be an actual service, software, or system (e.g., "Microsoft Excel", "Gmail", "Salesforce CRM", "PostgreSQL Database", "Slack")
   - NOT generic categories like "email system" - use specific real services
   - Must be plausible for this specific environment and user role
   - Should NOT duplicate existing components

   STRONGLY PREFER DOMAIN-SPECIFIC COMPONENTS:
   - Prioritize specialized software/services relevant to this specific environment and user role
   - Generic system tools (Terminal, Bash, Text Editor, File System) should only be proposed occasionally when truly essential
   - Think: What specialized tools would this specific user actually use day-to-day?
   - Examples: Instead of "Text Editor", propose "LaTeX Editor" for a researcher, "Code Editor with Linter" for a developer, "Markdown Editor" for documentation

2. Propose 3-6 tools for this component
   - You may choose any number within this range based on what makes sense for the component
   - Each tool should do ONE specific thing (Single Responsibility Principle)
   - Tools should be diverse and cover different operations for this component
   - Avoid "mega-tools" that try to do everything at once
   - Consider what the user might ask the AI agent to do with this component

   ENSURE VARIETY IN READ/WRITE OPERATIONS:
   - Include a MIX of read-only, write-only, and read-write tools
   - Read tools: Query/retrieve data without modification (e.g., list_emails, get_job_status, search_records)
   - Write tools: Create/modify/delete data (e.g., send_email, cancel_job, update_record, delete_file)
   - Read-write tools: Operations that both retrieve and modify (e.g., archive_and_summarize, process_and_update)
   - Realistic components have BOTH read and write capabilities - don't create read-only or write-only components

3. Format requirements:
   - Tool names MUST follow Python method naming (lowercase_with_underscores)
   - Tool names should indicate which component they interact with
   - Naming can be diverse: "read_excel_cell", "send_gmail", "query_salesforce_leads", "postgres_execute_query", "create_slack_channel"
   - Each tool should have clear, specific parameters (not 10+ parameters)

   DESCRIPTION STYLE: BRIEF
   - If BRIEF: Write short 1-2 sentence descriptions for all tools (e.g., "Sends an email to specified recipient.")
   - If DETAILED: Write comprehensive 3-6 sentence descriptions with behavior details, constraints, edge cases, return values
     Example: "Cancels a running SLURM job by job ID. If the job is already completed or cancelled, returns an error. Requires the job to be owned by the current user or admin privileges. Returns cancellation confirmation and final job status."
</task>

<response_format>
Respond with a JSON object in this exact format:
{
  "component_name": "Specific Real Service Name (e.g., Microsoft Excel, Gmail, Salesforce CRM)",
  "component_id": "lowercase_identifier (e.g., excel, gmail, salesforce)",
  "resources": {
    "resource_type": {
      "description": "What this resource represents",
      "fields": ["field1", "field2", "field3"]
    }
  },
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "tool_name_indicating_component",
        "description": "Clear description of what this tool does.",
        "operation_type": "read|write|read-write",
        "parameters": {
          "type": "object",
          "properties": {
            "param_name": {
              "type": "string",
              "description": "Parameter description."
            },
            "tags": {
              "type": "array",
              "items": {"type": "string"},
              "description": "List of tags (for array parameters, MUST include 'items' field)"
            }
          },
          "required": ["param_name"]
        }
      }
    }
  ]
}

IMPORTANT:
- Component must be a REAL service/software that would be used in this environment
- Tool names must be lowercase_with_underscores
- Tool names should make it clear which component they're for (naming convention can vary)
- Each tool should be focused and specific, not a mega-tool
- Each tool MUST specify operation_type: "read", "write", or "read-write"
  * "read" = retrieves/queries data without modification
  * "write" = creates/modifies/deletes data
  * "read-write" = both retrieves and modifies in a single operation
- ARRAY PARAMETERS: If a parameter has "type": "array", you MUST include an "items" field specifying the array element type
  * Example: {"type": "array", "items": {"type": "string"}}
  * Valid item types: "string", "number", "boolean", or object schemas

RESOURCES - Keep them SIMPLE:
- Define what data/entities this component manages (e.g., for SLURM: jobs, queue; for Gmail: emails, folders)
- Use 2-5 fields per resource (MAXIMUM 5 fields, only if absolutely necessary)
- Only include ESSENTIAL fields that tools actually need to read/modify
- DO NOT include: authentication details, permissions, access levels, audit logs, metadata timestamps
- DO NOT include any date or time fields (no created_at, updated_at, timestamp, submit_time, date fields). This is critical for evaluation purposes.
- Good example: job: [job_id, status, user, partition, priority]
- Bad example: job with 20+ fields including detailed permissions, logging, authentication, etc.

CRITICAL - RESOURCES MUST CONTAIN ACTUAL READABLE CONTENT:
- Resources MUST contain a field with ACTUAL READABLE CONTENT, not just references
- Path/URL fields are allowed as OPTIONAL METADATA, but only if a content field is also present
- Good: document: [doc_id, title, content, author] where "content" is the actual text
- Good: document: [doc_id, title, file_path, content, author] where both path AND content exist
- Bad: document: [doc_id, title, file_path, author] where "file_path" is the only data (no actual content)
- Good: email: [email_id, subject, body, sender] where "body" is the actual email text
- Bad: email: [email_id, subject, attachment_url, sender] where URL is the only data (no actual content)
- Good: dataset: [dataset_id, name, data, owner] where "data" is actual data content
- Bad: dataset: [dataset_id, name, root_path, owner] where "root_path" is the only data (no actual content)
- If representing file systems or data collections, define resources as the ACTUAL FILES/ITEMS with content

TOOLS - Return FULL data by default:
- Tools should return ALL fields for ALL matching resources (e.g., list_jobs returns jobs from ALL users, not just current user)
- DO NOT implement access controls or filtering in tool descriptions
- The agent should have full read access to all resource data
- Example: "list_slurm_jobs" should return all jobs in the queue, not just the user's jobs
- Example: "search_emails" should return all matching emails, not filtered by sender/recipient

Only respond with the JSON object, nothing else.
</response_format>

--- OUTPUT ---

{
  "component_name": "Lake Shore MeasureLINK",
  "component_id": "measurelink",
  "resources": {
    "experiment": {
      "description": "Configured MeasureLINK experiments with execution state.",
      "fields": ["experiment_id", "name", "recipe", "status"]
    },
    "dataset": {
      "description": "Recorded data products from MeasureLINK experiments.",
      "fields": ["dataset_id", "experiment_id", "name", "data"]
    },
    "note": {
      "description": "Free-text annotations attached to experiments in MeasureLINK.",
      "fields": ["note_id", "experiment_id", "content"]
    }
  },
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "measurelink_list_experiments",
        "description": "Lists all MeasureLINK experiments, optionally filtered by status. Returns full fields for every matching experiment.",
        "operation_type": "read",
        "parameters": {
          "type": "object",
          "properties": {
            "status": {
              "type": "string",
              "description": "Optional status filter (e.g., queued, running, completed, aborted)."
            }
          },
          "required": []
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "measurelink_get_dataset",
        "description": "Retrieves a single dataset by ID, including full data content.",
        "operation_type": "read",
        "parameters": {
          "type": "object",
          "properties": {
            "dataset_id": {
              "type": "string",
              "description": "The unique identifier of the dataset to retrieve."
            }
          },
          "required": ["dataset_id"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "measurelink_submit_experiment_recipe",
        "description": "Creates and queues a new experiment from a MeasureLINK recipe. Returns the created experiment with full fields.",
        "operation_type": "write",
        "parameters": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "description": "Human-readable experiment name."
            },
            "recipe": {
              "type": "string",
              "description": "Full MeasureLINK recipe text describing steps, setpoints, and logging."
            },
            "instruments": {
              "type": "array",
              "items": {"type": "string"},
              "description": "Optional list of instrument identifiers targeted by the recipe."
            }
          },
          "required": ["name", "recipe"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "measurelink_update_recipe",
        "description": "Replaces the recipe of an existing experiment. Returns the updated experiment for verification.",
        "operation_type": "write",
        "parameters": {
          "type": "object",
          "properties": {
            "experiment_id": {
              "type": "string",
              "description": "Identifier of the experiment to update."
            },
            "recipe": {
              "type": "string",
              "description": "Full replacement recipe text."
            }
          },
          "required": ["experiment_id", "recipe"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "measurelink_abort_experiment",
        "description": "Attempts to abort a queued or running experiment. Returns the experiment with its updated status.",
        "operation_type": "write",
        "parameters": {
          "type": "object",
          "properties": {
            "experiment_id": {
              "type": "string",
              "description": "Identifier of the experiment to abort."
            },
            "reason": {
              "type": "string",
              "description": "Optional human-readable reason appended to experiment notes."
            }
          },
          "required": ["experiment_id"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "measurelink_analyze_tc_and_add_note",
        "description": "Computes a Tc estimate from an experiment's dataset and appends a summary note to the experiment.",
        "operation_type": "read-write",
        "parameters": {
          "type": "object",
          "properties": {
            "experiment_id": {
              "type": "string",
              "description": "Experiment whose dataset will be analyzed and annotated."
            },
            "dataset_id": {
              "type": "string",
              "description": "Specific dataset to analyze; if omitted, uses the most recent dataset for the experiment."
            },
            "method": {
              "type": "string",
              "description": "Tc estimation method: resistivity_drop or levitation_onset."
            },
            "smoothing": {
              "type": "boolean",
              "description": "If true, applies light smoothing before detection."
            },
            "annotate_prefix": {
              "type": "string",
              "description": "Optional prefix included before the Tc summary in the note."
            }
          },
          "required": ["experiment_id", "method"]
        }
      }
    }
  ]
}

