From 7d7fb80d26d7a0550952cd898beaac8e9a857d8c Mon Sep 17 00:00:00 2001 From: Dmitry Persiyanov Date: Wed, 10 Jun 2026 20:39:11 +0200 Subject: [PATCH 1/3] Add Deep Company Research to the Extruct API skill New deep-research CLI resource (create/get/list/poll, mirroring deep-search: payload validation, pagination checks, poll loop sized for minutes-long runs at 15s x 240 attempts), a SKILL.md section covering when to use it vs Deep Search, Pro gating, depth/credit semantics, and how to read reports (citations, basis, degradation_reasons, failure_reason), plus a deep-company-research reference playbook for brief-writing, depth choice, and output-schema design. Marketplace bumped to 1.0.7. Co-Authored-By: Claude Fable 5 --- .claude-plugin/marketplace.json | 4 +- skills/extruct-api/SKILL.md | 70 ++++++- skills/extruct-api/agents/openai.yaml | 2 +- .../references/deep-company-research.md | 70 +++++++ skills/extruct-api/scripts/extruct-api | 177 ++++++++++++++++++ 5 files changed, 319 insertions(+), 4 deletions(-) create mode 100644 skills/extruct-api/references/deep-company-research.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 2724a1e..26da468 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -6,13 +6,13 @@ }, "metadata": { "description": "Official Extruct AI skills for company lookup, discovery, Deep Search, AI tables, enrichment, and people workflows", - "version": "1.0.6", + "version": "1.0.7", "repository": "https://github.com/extruct-ai/skills" }, "plugins": [ { "name": "extruct-skills", - "version": "1.0.6", + "version": "1.0.7", "description": "Official Extruct AI skill bundle for company lookup, semantic search, lookalike search, Deep Search, table operations, enrichment, and contact-finding workflows.", "source": "./", "strict": true, diff --git a/skills/extruct-api/SKILL.md b/skills/extruct-api/SKILL.md index 9c91df3..e3f7515 100644 --- a/skills/extruct-api/SKILL.md +++ b/skills/extruct-api/SKILL.md @@ -1,6 +1,6 @@ --- name: extruct-api -description: Run explicit Extruct API tasks through the bundled Extruct CLI. Covers Deep Search, semantic search, lookalike search, company and people tables, column operations, enrichment, and contact finding. +description: Run explicit Extruct API tasks through the bundled Extruct CLI. Covers Deep Search, Deep Company Research, semantic search, lookalike search, company and people tables, column operations, enrichment, and contact finding. --- # Extruct API @@ -45,6 +45,7 @@ This section covers the default operating intent of the skill: identify the Extr - if the user provides an Extruct task URL or a raw task UUID, treat it as an existing Deep Search task first - known company lookup: fetch the canonical company profile for one domain or UUID - company discovery: semantic search, lookalike search, or Deep Search + - company research report: Deep Company Research for a deep, cited report on one target - existing table operation: inspect, add/update rows or columns, run, poll, read - company-table workflow: enrich or score companies in a reusable table - people workflow: find people at companies or enrich existing people rows @@ -84,6 +85,7 @@ If none of those conditions is true, stop before running Pro-only commands and t Pro-only actions in this skill: - Deep Search mutations: `deep-search create`, `deep-search resume`, `deep-search pause` +- Deep Research mutations: `deep-research create` - Table mutations: `tables create`, `tables update`, `tables delete`, `tables clone`, `tables run`, `rows create`, `rows update`, `rows delete`, `columns add`, `columns update`, `columns delete` ## Resolve Extruct Identifiers @@ -316,6 +318,71 @@ If Deep Search payload fields, task states, or resume behavior are unclear, veri Read `references/finding-companies.md` when the task is a fuller company-discovery workflow instead of a single search command. +### Deep Company Research + +Use Deep Research when the user wants a deep, cited report on one research target — account planning, buyer research, initiative summaries, diligence — rather than a list of companies. For discovering many companies, use Deep Search; for repeatable enrichment across a list, use tables. + +`deep-research create` is Pro-gated. Run the plan-access preflight before it. + +Typical asks: + +- "research Shell for me: buying centers, initiatives, sales angles" +- "build an account plan brief for Stripe" +- "do diligence on this company and give me a sourced report" + +Create a task (markdown report): + +```bash + deep-research create --payload '{"brief":"Help me break into Shell. Find buying centers, recent initiatives, and practical sales angles.","depth":"medium"}' +``` + +Create a task with structured output (`--payload-file` preferred for schemas): + +```bash + deep-research create --payload-file research.json +``` + +`research.json`: + +```json +{ + "brief": "Summarize Stripe's current enterprise initiatives for an account plan.", + "depth": "high", + "output_schema": { + "type": "object", + "properties": { + "summary": {"type": "string"}, + "recommended_angles": {"type": "array", "items": {"type": "string"}}, + "risks": {"type": "array", "items": {"type": "string"}} + }, + "required": ["summary", "recommended_angles", "risks"] + } +} +``` + +Inspect, list, and wait for completion: + +```bash + deep-research list --limit 20 + deep-research get + deep-research poll +``` + +Depth and billing: + +- `depth` sets the research-agent budget: `medium` = 25, `high` = 50, `xhigh` = 75. +- Creating a task requires the full budget in available credits; the user is billed only for agents that actually run (1 credit each). Failed tasks refund all charges. +- If create returns `insufficient_credits` with `required_credits`/`available_credits`, a lower depth may still fit — offer it. + +Reading the result: + +- Tasks take minutes. `deep-research poll` blocks until `status` is `done` or `failed`; progress counters are `iterations`, `agents`, `sources`. +- `report.kind` is `markdown` (citations like `[1]` resolve against `report.sources`) or `schema` (`fields` conforming to the output schema, `basis` mapping each field to supporting source ids, plus `sources`). +- **Always surface `report.degradation_reasons` to the user** — plain-language notes when coverage was reduced (early finalization, failed research agents). Empty means a clean run. +- On `failed`, read `failure_reason` and relay it: a rejected brief includes suggestions for fixing it. Failed tasks are refunded. + +Read `references/deep-company-research.md` for brief-writing, depth choice, and output-schema design guidance. + ## Operate Existing Tables Use these commands when the user already has a table and wants to inspect it, change rows or columns, run new work, or read results. @@ -780,6 +847,7 @@ Check that: - `references/column-guide.md`: column design rules plus a comprehensive library of good column configs - `references/finding-companies.md`: choose and operate semantic search, lookalike, and Deep Search +- `references/deep-company-research.md`: write briefs, choose depth, and design output schemas for Deep Research - `references/researching-companies.md`: build or extend company research tables safely - `references/finding-people-at-companies.md`: branch from company tables into people workflows - `references/researching-people.md`: enrich standalone or generated people tables diff --git a/skills/extruct-api/agents/openai.yaml b/skills/extruct-api/agents/openai.yaml index 6baf7ec..d189e73 100644 --- a/skills/extruct-api/agents/openai.yaml +++ b/skills/extruct-api/agents/openai.yaml @@ -1,6 +1,6 @@ interface: display_name: "Extruct API" - short_description: "Company discovery, Deep Search, AI tables, enrichment, and people workflows" + short_description: "Company discovery, Deep Search, Deep Research, AI tables, enrichment, and people workflows" icon_small: "./assets/logo.svg" icon_large: "./assets/logo.svg" brand_color: "#4D56F3" diff --git a/skills/extruct-api/references/deep-company-research.md b/skills/extruct-api/references/deep-company-research.md new file mode 100644 index 0000000..76fef20 --- /dev/null +++ b/skills/extruct-api/references/deep-company-research.md @@ -0,0 +1,70 @@ +# Deep Company Research Playbook + +Deep Research turns a free-text brief about one research target into a cited report. +A reasoning agent plans the research, fans out research agents that gather evidence, +and synthesizes the result. This playbook covers writing briefs, choosing depth, +designing output schemas, and reading reports honestly. + +## When this path, when another + +- One target, deep sourced report (account plan, buyer research, diligence): Deep Research. +- Many companies matching criteria: Deep Search. +- The same questions across a list of companies, repeatably: a company table. +- One company's profile facts, instantly: company lookup. + +## Write the brief like a request to an analyst + +Good briefs name the target and the decision the report should support: + +- Good: "Help me break into Shell. Find buying centers, recent initiatives, and practical sales angles for an enterprise data product." +- Good: "Diligence brief on Acme Robotics: funding history, key customers, competitive position, and open risks." +- Bad: "Tell me about Shell." (no decision to support; the report will be unfocused) + +Include context the agents cannot guess: what you sell, the angle you care about, time +windows when freshness matters. The brief can be long (up to 20,000 characters) — +pasting context is fine. + +Vague-but-valid briefs run; truly targetless or unusable briefs are rejected +asynchronously with suggestions in `failure_reason`, and nothing is charged. + +## Choose depth deliberately + +- `medium` (25 agents): default. Right for most account plans and single-question research. +- `high` (50): multi-angle research on a large target, or schema mode with many fields. +- `xhigh` (75): exhaustive coverage; use when the user explicitly wants maximum depth. + +Creating a task requires the full budget in available credits, but billing is per agent +that actually runs — a focused brief at `high` often finishes well under budget. If +create fails with `insufficient_credits`, the error includes `required_credits` and +`available_credits`; offer a lower depth. + +## Design output schemas narrowly + +Schema mode (`output_schema`) is for machine-readable reports. Rules of thumb: + +- A handful of fields, each naming one decision-relevant fact or bounded list. +- Use arrays of strings for angles, risks, initiatives; strings for summaries; numbers + only for genuinely numeric facts. +- The schema must be a JSON Schema object (`"type": "object"`); it is validated in + full at creation time, so a malformed nested schema fails fast. +- A `done` schema report is guaranteed to conform. Per-field `basis` (source ids) is + the audit trail — treat fields with an empty basis as unsupported. + +## Run and read + +```bash + deep-research create --payload-file research.json + deep-research poll +``` + +Reading the report honestly: + +- Markdown reports cite sources as `[1]`-style ids resolving against `report.sources`. + Do not strip the citations when relaying to the user. +- **Always check `report.degradation_reasons`** and show them with the report. They say, + in plain language, when research stopped early (budget or step limit) or when some + research agents failed. An empty list means a clean run. +- On `failed`, relay `failure_reason`. Rejected briefs include concrete suggestions — + offer to retry with a fixed brief. Failed tasks refund all their charges. +- Progress while running: `iterations` (analysis steps), `agents` (billed research + agents), `sources` (unique sources collected). diff --git a/skills/extruct-api/scripts/extruct-api b/skills/extruct-api/scripts/extruct-api index 41876e4..3d475bf 100755 --- a/skills/extruct-api/scripts/extruct-api +++ b/skills/extruct-api/scripts/extruct-api @@ -35,6 +35,8 @@ DEFAULT_POLL_MAX_ATTEMPTS = 60 DEFAULT_DEEP_SEARCH_RESULTS_LIMIT = 50 DEFAULT_DEEP_SEARCH_POLL_INTERVAL_SECONDS = 10.0 DEFAULT_DEEP_SEARCH_POLL_MAX_ATTEMPTS = 120 +DEFAULT_DEEP_RESEARCH_POLL_INTERVAL_SECONDS = 15.0 +DEFAULT_DEEP_RESEARCH_POLL_MAX_ATTEMPTS = 240 ALLOWED_TABLE_SORT_VALUES = ("-created_at", "created_at", "name", "-name", "num_rows", "-num_rows") EXIT_SUCCESS = 0 @@ -484,6 +486,12 @@ def _deep_search_is_complete(payload: Any) -> bool: return payload.get("status") in ("done", "failed") +def _deep_research_is_complete(payload: Any) -> bool: + if not isinstance(payload, dict): + return False + return payload.get("status") in ("done", "failed") + + def _validate_payload_object(payload: Any, *, path: str) -> tuple[Any | None, int]: if isinstance(payload, dict): return None, EXIT_SUCCESS @@ -493,6 +501,34 @@ def _validate_payload_object(payload: Any, *, path: str) -> tuple[Any | None, in ) +def _validate_deep_research_create_payload(payload: Any, *, path: str) -> tuple[Any | None, int]: + payload_error, payload_code = _validate_payload_object(payload, path=path) + if payload_error is not None: + return payload_error, payload_code + + brief = payload.get("brief") + if not isinstance(brief, str) or not brief.strip(): + return _cli_error( + message="Invalid payload: 'brief' is required and must be a non-empty string.", + path=path, + ) + + if "depth" in payload and payload["depth"] not in ("medium", "high", "xhigh"): + return _cli_error( + message="Invalid payload: 'depth' must be one of 'medium', 'high', 'xhigh'.", + path=path, + ) + + if "output_schema" in payload and payload["output_schema"] is not None: + if not isinstance(payload["output_schema"], dict): + return _cli_error( + message="Invalid payload: 'output_schema' must be a JSON Schema object.", + path=path, + ) + + return None, EXIT_SUCCESS + + def _validate_deep_search_create_payload(payload: Any, *, path: str) -> tuple[Any | None, int]: payload_error, payload_code = _validate_payload_object(payload, path=path) if payload_error is not None: @@ -905,6 +941,44 @@ def _build_parser() -> argparse.ArgumentParser: deep_search_poll.add_argument("--interval", type=float, default=DEFAULT_DEEP_SEARCH_POLL_INTERVAL_SECONDS) deep_search_poll.add_argument("--max-attempts", type=int, default=DEFAULT_DEEP_SEARCH_POLL_MAX_ATTEMPTS) + deep_research = resources.add_parser( + "deep-research", + help="Deep Company Research task commands. Tasks are asynchronous and produce one cited report.", + parents=[global_options], + ) + deep_research_actions = deep_research.add_subparsers(dest="action", required=True) + + deep_research_list = deep_research_actions.add_parser( + "list", help="List Deep Research tasks, newest first.", parents=[global_options] + ) + deep_research_list.add_argument("--offset", type=int, default=DEFAULT_LIST_OFFSET) + deep_research_list.add_argument("--limit", type=int, default=DEFAULT_LIST_LIMIT) + + deep_research_create = deep_research_actions.add_parser( + "create", + help="Create a Deep Research task. Requires payload with non-empty brief.", + parents=[global_options], + ) + _add_payload_args(deep_research_create) + + deep_research_get = deep_research_actions.add_parser( + "get", help="Get a Deep Research task.", parents=[global_options] + ) + deep_research_get.add_argument("task_id") + + deep_research_poll = deep_research_actions.add_parser( + "poll", + help="Poll a Deep Research task until status=done or status=failed.", + parents=[global_options], + ) + deep_research_poll.add_argument("task_id") + deep_research_poll.add_argument( + "--interval", type=float, default=DEFAULT_DEEP_RESEARCH_POLL_INTERVAL_SECONDS + ) + deep_research_poll.add_argument( + "--max-attempts", type=int, default=DEFAULT_DEEP_RESEARCH_POLL_MAX_ATTEMPTS + ) + return parser @@ -1006,6 +1080,18 @@ def _deep_search_method_path(action: str, task_id: str | None = None) -> tuple[s raise ValueError(f"Unsupported deep-search action: {action}") +def _deep_research_method_path(action: str, task_id: str | None = None) -> tuple[str, str]: + if action == "list": + return "GET", "/v1/deep_research_tasks" + if action == "create": + return "POST", "/v1/deep_research_tasks" + if task_id is None: + raise ValueError("task_id is required for this deep-research action.") + if action in ("get", "poll"): + return "GET", f"/v1/deep_research_tasks/{task_id}" + raise ValueError(f"Unsupported deep-research action: {action}") + + def _handle_auth(args: argparse.Namespace) -> int: method, path = _auth_method_path(args.action) return _execute_request(args, method=method, path=path) @@ -1444,6 +1530,95 @@ def _handle_deep_search(args: argparse.Namespace) -> int: return code +def _handle_deep_research(args: argparse.Namespace) -> int: + if args.action == "list": + method, path = _deep_research_method_path("list") + pagination_error, pagination_error_code = _validate_pagination(args.offset, args.limit, path=path) + if pagination_error is not None: + _json_print(pagination_error, args.pretty) + return pagination_error_code + return _execute_request( + args, + method=method, + path=path, + query={"offset": args.offset, "limit": args.limit}, + ) + + if args.action == "create": + method, path = _deep_research_method_path("create") + payload, payload_error, payload_code = _load_payload(args.payload, args.payload_file, path=path) + if payload_error is not None: + _json_print(payload_error, args.pretty) + return payload_code + validation_error, validation_code = _validate_deep_research_create_payload(payload, path=path) + if validation_error is not None: + _json_print(validation_error, args.pretty) + return validation_code + return _execute_request(args, method=method, path=path, payload=payload) + + task_error, task_code = _validate_non_empty( + args.task_id, + flag="task_id", + path="/v1/deep_research_tasks/{task_id}", + ) + if task_error is not None: + _json_print(task_error, args.pretty) + return task_code + + method, path = _deep_research_method_path(args.action, task_id=args.task_id) + + if args.action == "get": + return _execute_request(args, method=method, path=path) + + if args.action == "poll": + interval_error, interval_code = _validate_positive_number(args.interval, flag="--interval", path=path) + if interval_error is not None: + _json_print(interval_error, args.pretty) + return interval_code + attempts_error, attempts_code = _validate_positive_number( + args.max_attempts, + flag="--max-attempts", + path=path, + ) + if attempts_error is not None: + _json_print(attempts_error, args.pretty) + return attempts_code + + token, token_error, token_exit = _resolve_token(method=method, path=path) + if token is None: + _json_print(token_error, args.pretty) + return token_exit + + for attempt in range(args.max_attempts): + response_payload, exit_code = _make_request( + base_url=args.base_url, + token=token, + method=method, + path=path, + timeout=args.timeout, + ) + if exit_code != EXIT_SUCCESS: + _json_print(response_payload, args.pretty) + return exit_code + if _deep_research_is_complete(response_payload): + _json_print(response_payload, args.pretty) + return EXIT_SUCCESS + if attempt + 1 < args.max_attempts: + time.sleep(args.interval) + + timeout_error, timeout_code = _cli_error( + message="Deep Research polling timed out before reaching a terminal state.", + path=path, + details={"max_attempts": args.max_attempts, "interval": args.interval}, + ) + _json_print(timeout_error, args.pretty) + return timeout_code + + error, code = _cli_error(message="Unsupported deep-research action.", path="/v1/deep_research_tasks") + _json_print(error, args.pretty) + return code + + def main() -> int: parser = _build_parser() args = parser.parse_args(_normalize_argv(sys.argv[1:])) @@ -1463,6 +1638,8 @@ def main() -> int: return _handle_columns(args) if args.resource == "deep-search": return _handle_deep_search(args) + if args.resource == "deep-research": + return _handle_deep_research(args) error, code = _cli_error(message="Unsupported resource.", path="/") _json_print(error, args.pretty) From dd72e3949cb686f2a31a56e09a8c9bf76c43a365 Mon Sep 17 00:00:00 2001 From: Dmitry Persiyanov Date: Wed, 10 Jun 2026 21:01:48 +0200 Subject: [PATCH 2/3] Teach agents to write detailed deep research briefs --- skills/extruct-api/SKILL.md | 10 +++++-- .../references/deep-company-research.md | 30 +++++++++++++------ 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/skills/extruct-api/SKILL.md b/skills/extruct-api/SKILL.md index e3f7515..680ad97 100644 --- a/skills/extruct-api/SKILL.md +++ b/skills/extruct-api/SKILL.md @@ -330,10 +330,16 @@ Typical asks: - "build an account plan brief for Stripe" - "do diligence on this company and give me a sourced report" +Write the brief as a detailed paragraph, not a one-liner. Pack in everything you know +from the conversation: what the user sells or researches, who the target buyer is, what +decision the report supports, constraints, and time windows. The more context and +specifics the brief carries, the better the report. If the user's ask is thin, ask one +or two clarifying questions before creating the task. + Create a task (markdown report): ```bash - deep-research create --payload '{"brief":"Help me break into Shell. Find buying centers, recent initiatives, and practical sales angles.","depth":"medium"}' + deep-research create --payload '{"brief":"We sell a cloud cost-optimization platform to large enterprises; typical buyers are VPs of Infrastructure and FinOps leads. I am preparing outreach to Shell. Research how Shell'"'"'s IT and digital organization is structured, who owns cloud infrastructure and FinOps decisions, which cloud, data, or efficiency initiatives they announced in the last 18 months, and which vendors or system integrators they already work with. I want practical conversation angles tied to live initiatives, plus any signals of cost-cutting programs or budget pressure.","depth":"medium"}' ``` Create a task with structured output (`--payload-file` preferred for schemas): @@ -346,7 +352,7 @@ Create a task with structured output (`--payload-file` preferred for schemas): ```json { - "brief": "Summarize Stripe's current enterprise initiatives for an account plan.", + "brief": "We provide fraud-prevention APIs for fintech platforms and are building an account plan for Stripe. Summarize Stripe's enterprise product initiatives from the last 12 months (payments, billing, risk, AI), identify concrete product or partnership angles where a fraud-prevention vendor could plug in, and flag risks that could stall a deal, such as in-house solutions, recent vendor consolidation, or compliance constraints.", "depth": "high", "output_schema": { "type": "object", diff --git a/skills/extruct-api/references/deep-company-research.md b/skills/extruct-api/references/deep-company-research.md index 76fef20..f6e8e65 100644 --- a/skills/extruct-api/references/deep-company-research.md +++ b/skills/extruct-api/references/deep-company-research.md @@ -14,15 +14,27 @@ designing output schemas, and reading reports honestly. ## Write the brief like a request to an analyst -Good briefs name the target and the decision the report should support: - -- Good: "Help me break into Shell. Find buying centers, recent initiatives, and practical sales angles for an enterprise data product." -- Good: "Diligence brief on Acme Robotics: funding history, key customers, competitive position, and open risks." -- Bad: "Tell me about Shell." (no decision to support; the report will be unfocused) - -Include context the agents cannot guess: what you sell, the angle you care about, time -windows when freshness matters. The brief can be long (up to 20,000 characters) — -pasting context is fine. +Good briefs are detailed paragraphs that name the target, the requester's own context, +and the decision the report should support. One-liners produce unfocused reports. + +- Good: "We sell a cloud cost-optimization platform to large enterprises; typical + buyers are VPs of Infrastructure and FinOps leads. I am preparing outreach to Shell. + Research how Shell's IT and digital organization is structured, who owns cloud + infrastructure and FinOps decisions, which cloud, data, or efficiency initiatives + they announced in the last 18 months, and which vendors or system integrators they + already work with. I want practical conversation angles tied to live initiatives, + plus any signals of cost-cutting programs or budget pressure." +- Good: "We are a seed-stage investor evaluating Acme Robotics for a follow-on round. + Build a diligence brief: funding history and investors, key customers and revenue + signals, the competitive landscape for warehouse automation, recent leadership + changes, and open risks we should pressure-test in the partner meeting." +- Bad: "Help me break into Shell." (no context about what you sell or who you target) +- Bad: "Tell me about Stripe." (no decision to support; the report will be unfocused) + +Include everything the research agents cannot guess: what you sell, who your buyer is, +the angle you care about, time windows when freshness matters, what you already know. +The brief can be long (up to 20,000 characters) — pasting context is encouraged, and +more specific briefs reliably produce better reports. Vague-but-valid briefs run; truly targetless or unusable briefs are rejected asynchronously with suggestions in `failure_reason`, and nothing is charged. From bdda3292915c3831cdd5024bd9b4cdc56e1f4cef Mon Sep 17 00:00:00 2001 From: Dmitry Persiyanov Date: Wed, 10 Jun 2026 21:17:31 +0200 Subject: [PATCH 3/3] Reposition Deep Research as research on companies and people People are first-class targets ("research this lead and the team they work with"), so the section, routing, playbook, and examples drop the company-only framing: renamed references/deep-research.md, added a people-brief example to SKILL.md and the playbook, a people typical-ask, and a cross-reference from the Research People section. Co-Authored-By: Claude Fable 5 --- skills/extruct-api/SKILL.md | 21 +++++++++++++------ ...p-company-research.md => deep-research.md} | 8 +++++-- 2 files changed, 21 insertions(+), 8 deletions(-) rename skills/extruct-api/references/{deep-company-research.md => deep-research.md} (86%) diff --git a/skills/extruct-api/SKILL.md b/skills/extruct-api/SKILL.md index 680ad97..85620e6 100644 --- a/skills/extruct-api/SKILL.md +++ b/skills/extruct-api/SKILL.md @@ -1,6 +1,6 @@ --- name: extruct-api -description: Run explicit Extruct API tasks through the bundled Extruct CLI. Covers Deep Search, Deep Company Research, semantic search, lookalike search, company and people tables, column operations, enrichment, and contact finding. +description: Run explicit Extruct API tasks through the bundled Extruct CLI. Covers Deep Search, Deep Research on companies and people, semantic search, lookalike search, company and people tables, column operations, enrichment, and contact finding. --- # Extruct API @@ -45,7 +45,7 @@ This section covers the default operating intent of the skill: identify the Extr - if the user provides an Extruct task URL or a raw task UUID, treat it as an existing Deep Search task first - known company lookup: fetch the canonical company profile for one domain or UUID - company discovery: semantic search, lookalike search, or Deep Search - - company research report: Deep Company Research for a deep, cited report on one target + - research report: Deep Research for a deep, cited report on one target — a company, a person, or a team - existing table operation: inspect, add/update rows or columns, run, poll, read - company-table workflow: enrich or score companies in a reusable table - people workflow: find people at companies or enrich existing people rows @@ -318,9 +318,9 @@ If Deep Search payload fields, task states, or resume behavior are unclear, veri Read `references/finding-companies.md` when the task is a fuller company-discovery workflow instead of a single search command. -### Deep Company Research +### Deep Research -Use Deep Research when the user wants a deep, cited report on one research target — account planning, buyer research, initiative summaries, diligence — rather than a list of companies. For discovering many companies, use Deep Search; for repeatable enrichment across a list, use tables. +Use Deep Research when the user wants a deep, cited report on one research target — a company, a person, or a team: account planning, buyer research, researching a lead before outreach, initiative summaries, diligence. For discovering many companies, use Deep Search; for repeatable enrichment across a list, use tables. `deep-research create` is Pro-gated. Run the plan-access preflight before it. @@ -328,6 +328,7 @@ Typical asks: - "research Shell for me: buying centers, initiatives, sales angles" - "build an account plan brief for Stripe" +- "research this lead and the team they work with before my call" - "do diligence on this company and give me a sourced report" Write the brief as a detailed paragraph, not a one-liner. Pack in everything you know @@ -342,6 +343,12 @@ Create a task (markdown report): deep-research create --payload '{"brief":"We sell a cloud cost-optimization platform to large enterprises; typical buyers are VPs of Infrastructure and FinOps leads. I am preparing outreach to Shell. Research how Shell'"'"'s IT and digital organization is structured, who owns cloud infrastructure and FinOps decisions, which cloud, data, or efficiency initiatives they announced in the last 18 months, and which vendors or system integrators they already work with. I want practical conversation angles tied to live initiatives, plus any signals of cost-cutting programs or budget pressure.","depth":"medium"}' ``` +People are first-class targets — include the user's own context and the profile to research: + +```bash + deep-research create --payload '{"brief":"Here is my company: example.com. We sell AI-powered sales-enablement software to mid-market B2B teams. Research this person and the team they work with: https://www.linkedin.com/in/example-profile. I want their role and scope, what their team owns, recent initiatives or public statements, tools they already use, and the best angle to open a conversation.","depth":"medium"}' +``` + Create a task with structured output (`--payload-file` preferred for schemas): ```bash @@ -387,7 +394,7 @@ Reading the result: - **Always surface `report.degradation_reasons` to the user** — plain-language notes when coverage was reduced (early finalization, failed research agents). Empty means a clean run. - On `failed`, read `failure_reason` and relay it: a rejected brief includes suggestions for fixing it. Failed tasks are refunded. -Read `references/deep-company-research.md` for brief-writing, depth choice, and output-schema design guidance. +Read `references/deep-research.md` for brief-writing, depth choice, and output-schema design guidance. ## Operate Existing Tables @@ -683,6 +690,8 @@ Use broader role families for coverage, such as `sales leadership`, and exact ti Use this path when the user already has people rows or already has a generated child `people` table and now wants enrichment, contact data, or derived fields. +For a deep one-off report on a single person or team (rather than repeatable table enrichment), use Deep Research instead — see the Deep Research section above. + Typical asks: - "find work emails for these people" @@ -853,7 +862,7 @@ Check that: - `references/column-guide.md`: column design rules plus a comprehensive library of good column configs - `references/finding-companies.md`: choose and operate semantic search, lookalike, and Deep Search -- `references/deep-company-research.md`: write briefs, choose depth, and design output schemas for Deep Research +- `references/deep-research.md`: write briefs, choose depth, and design output schemas for Deep Research - `references/researching-companies.md`: build or extend company research tables safely - `references/finding-people-at-companies.md`: branch from company tables into people workflows - `references/researching-people.md`: enrich standalone or generated people tables diff --git a/skills/extruct-api/references/deep-company-research.md b/skills/extruct-api/references/deep-research.md similarity index 86% rename from skills/extruct-api/references/deep-company-research.md rename to skills/extruct-api/references/deep-research.md index f6e8e65..765e723 100644 --- a/skills/extruct-api/references/deep-company-research.md +++ b/skills/extruct-api/references/deep-research.md @@ -1,6 +1,6 @@ -# Deep Company Research Playbook +# Deep Research Playbook -Deep Research turns a free-text brief about one research target into a cited report. +Deep Research turns a free-text brief about one research target — a company, a person, or a team — into a cited report. A reasoning agent plans the research, fans out research agents that gather evidence, and synthesizes the result. This playbook covers writing briefs, choosing depth, designing output schemas, and reading reports honestly. @@ -8,6 +8,7 @@ designing output schemas, and reading reports honestly. ## When this path, when another - One target, deep sourced report (account plan, buyer research, diligence): Deep Research. +- A person or team — research a lead before outreach or a meeting: Deep Research. - Many companies matching criteria: Deep Search. - The same questions across a list of companies, repeatably: a company table. - One company's profile facts, instantly: company lookup. @@ -28,11 +29,14 @@ and the decision the report should support. One-liners produce unfocused reports Build a diligence brief: funding history and investors, key customers and revenue signals, the competitive landscape for warehouse automation, recent leadership changes, and open risks we should pressure-test in the partner meeting." +- Good: "Here is my company: example.com. We sell AI-powered sales-enablement software to mid-market B2B teams. Research this person and the team they work with: https://www.linkedin.com/in/example-profile. I want their role and scope, what their team owns, recent initiatives or public statements, tools they already use, and the best angle to open a conversation." - Bad: "Help me break into Shell." (no context about what you sell or who you target) - Bad: "Tell me about Stripe." (no decision to support; the report will be unfocused) Include everything the research agents cannot guess: what you sell, who your buyer is, the angle you care about, time windows when freshness matters, what you already know. +For people targets, include the LinkedIn profile URL (or full name plus company) and +your own company and offer — the report is only as targeted as the brief. The brief can be long (up to 20,000 characters) — pasting context is encouraged, and more specific briefs reliably produce better reports.