{"skills":[{"name":"doc-compare","description":"Compare two or more separate documents, or two sections of one — what each says, where they agree, where they differ, and where one is silent. Use when the user explicitly asks how documents (or versions) differ, which is better or stricter, or what changed — including phrasing like \"compare X and Y\" or \"detailed comparison of X and Y\" where X and Y are the two things to diff, even if they read as two named entities. A document merely being ABOUT two parties, two entities, or a discussion between them is NOT a comparison — that is content to summarise or search, not two sources to diff. The test is the verb — \"discussed/happened/ negotiated between X and Y\" is content (use rag-query, or doc-summary for one document), while \"compare/differ/versus/which is better/what changed\" is a diff (use doc-compare).","purposes":["analytics","research"],"modalities":["unstructured"]},{"name":"doc-summary","description":"Summarise a document that has already been indexed — what it says, in the order it says it, with citations. Use when the user asks what a document is about, for an overview, the key points, or a recap. For answering a SPECIFIC question from documents, use rag-query instead; for extracting tables into a spreadsheet, use pdf-to-excel.","purposes":["research","analytics"],"modalities":["unstructured"]},{"name":"document-draft","description":"Draft a new document — proposal, SOW, point of view, report — grounded in indexed documents and explicit about what is missing. Use when asked to write or produce a document; for answering a question from documents, use rag-query.","purposes":["authoring","research"],"modalities":["unstructured"]},{"name":"interview-prep","description":"Prepare interview questions for a specific candidate, grounded in their resume and the job's criteria. Use when someone is about to interview a named person. For scoring or ranking applicants, use resume-screening instead.","purposes":["authoring"],"modalities":["unstructured"]},{"name":"job-intake","description":"Turn a described role into a job posting with its evaluation criteria. Use when someone wants to create, open or post a job. For screening candidates against an existing job, use resume-screening instead.","purposes":["automation"],"modalities":["unstructured"]},{"name":"pdf-to-excel","description":"Extract tables from a PDF into a spreadsheet. Use when the user asks to convert, extract, or pull tables out of a PDF document. For answering questions ABOUT what documents say, use rag-query instead.","purposes":["automation"],"modalities":["unstructured"]},{"name":"rag-ingest","description":"Index documents so they can be searched later — parse, chunk, tag, embed, index. Use when the user uploads or adds documents to a corpus. For asking questions of already-indexed documents, use rag-query instead.","purposes":["automation"],"modalities":["unstructured"]},{"name":"rag-query","description":"Answer a question from documents that have already been indexed — retrieve, judge, retrieve again if thin, and synthesise a cited answer. Use when the user asks what documents say about something. For adding new documents, use rag-ingest instead.","purposes":["research","analytics"],"modalities":["unstructured"]},{"name":"resume-screening","description":"Screen resumes against a job and rank the candidates, with the evidence behind each score. Use when someone has applicants to assess for an existing role. For preparing to interview a specific candidate, use interview-prep instead.","purposes":["analytics"],"modalities":["unstructured"]},{"name":"suggest-followups","description":"Propose 2-4 grounded next turns after an answer already exists — go deeper on a section, ask for risks, compare with another cited document. Use when a plan step runs after synthesis to offer follow-ups, never in place of answering a question. For answering a question itself, use rag-query instead; this never retrieves anything of its own.","purposes":["research","analytics"],"modalities":["unstructured"]}],"agents":[{"name":"comparator","description":"Compare two or more separate documents, or two sections of one — what each says, where they agree, where they differ, and where one is silent. Use when the user explicitly asks how documents (or versions) differ, which is better, or what changed — including phrasing like \"compare X and Y\" or \"detailed comparison of X and Y\" where X and Y are the two things to diff, even if they read as two named entities. A document merely being ABOUT two parties, two entities, or a discussion between them is NOT a comparison — that is content to summarise or search, not two sources to diff. The test is the verb — \"discussed/happened/negotiated between X and Y\" is content (use rag-query, or doc-summary for one document), while \"compare/differ/versus/which is better/what changed\" is a diff (use doc-compare).","model":"gpt-5.6-terra","tools":["doc.list","doc.compare_retrieve","doc.fetch","doc.search_raw"],"scopes":["doc.read"]},{"name":"confidence_scorer","description":"Score how far a cleaned table can be trusted, by independently re-extracting it from the source and comparing. Use after postprocessor, before anything ships the data. Reports discrepancies and a reliability score; it does not correct them.","model":"gemini-2.5-pro","tools":[],"scopes":["doc.read"]},{"name":"doc_classifier","description":"Decide what kind of document this is — its form, its subject area, and what it contains. Use when a document is ingested, before it is indexed. For assessing whether a scan is good enough to extract from, use quality_gate instead.","model":"gemini-2.5-flash","tools":[],"scopes":["doc.read"]},{"name":"doc_drafter","description":"Draft a new document — proposal, SOW, point of view, report — grounded in indexed documents and explicit about what is missing. Use when asked to write or produce a document, not when asked what documents say (rag-search) or to condense one (summariser).","model":"gpt-5.6-terra","tools":["doc.list","doc.fetch","doc.search_raw","gen.docx","io.s3_upload"],"scopes":["doc.read"]},{"name":"interview_questions","description":"Generate interviewer-ready questions grounded in a specific candidate's resume evidence and the job's parameters. Use when preparing to interview someone. Produces questions only — no scores, no assessment, no model answers.","model":"gemini-2.5-pro","tools":[],"scopes":["candidate.read"]},{"name":"job_fitment_parameter","description":"Derive the ten resume-verifiable criteria that separate strong candidates from average ones for a given job description. Use after a job is parsed and before any resume is screened — every later score is measured against these.","model":"gemini-2.5-pro","tools":[],"scopes":["job.read"]},{"name":"job_intake_parser","description":"Turn a free-form job description into the structured fields a job posting needs — title, type, location, category, compensation, experience. Use when someone describes a role in prose and it must become a record.","model":"gemini-2.5-flash","tools":[],"scopes":["job.read"]},{"name":"postprocessor","description":"Clean raw OCR table output — fix misread characters, restore rows the scan dropped, and normalise cells against the document's own layout. Use after OCR and before confidence scoring. For analysing what a table MEANS rather than repairing it, use table_analyst instead.","model":"gemini-2.5-flash","tools":[],"scopes":["doc.read"]},{"name":"quality_gate","description":"Assess whether a scanned document is good enough to extract from — rotation, skew, blur, blank pages, page count. Use before OCR, to decide whether preprocessing is needed. Returns evidence and a pass/fail, not a repaired document.","model":"gemini-2.5-flash","tools":["struct.preprocess"],"scopes":["doc.read"]},{"name":"rag_confidence_scorer","description":"Judge whether a synthesised answer covers the query and cites its claims, then score it via doc.retrieval_score and doc.completeness_score. Use after the synthesiser writes an answer. Returns a classification and a confidence band, not a repaired answer.","model":"gpt-5.4","tools":["doc.retrieval_score","doc.completeness_score"],"scopes":["doc.read"]},{"name":"rag_search","description":"Answer a question from indexed documents — search, judge what came back, search again if it is thin, and synthesise a cited answer. Covers pictures, diagrams, and slides already indexed, not only prose. Use when the user asks what documents say, or asks to see something already in one. For extracting tables out of a PDF, use pdf_to_excel instead.","model":"gpt-5.6-terra","tools":["doc.list","doc.search_raw"],"scopes":["doc.read"]},{"name":"resume_evaluation","description":"Score a candidate against the job's fitment parameters, using the evidence resume_intelligence collected. Use after that step, to rank candidates. Produces scores with reasons; it does not generate interview questions.","model":"gemini-2.5-pro","tools":[],"scopes":["candidate.read"]},{"name":"resume_intelligence","description":"Read a resume against a job's fitment parameters and collect the evidence for each — what the candidate actually did, where it says so. Use before resume_evaluation. Gathers evidence; it does not score or rank.","model":"gemini-2.5-pro","tools":[],"scopes":["candidate.read"]},{"name":"suggestion_generator","description":"Propose 2-4 grounded next turns after an answer has already been given — go deeper on a section, ask for risks, compare with another cited document. Runs after synthesis, on the answer that already exists. Not for answering a question itself — for that, use rag-query instead.","model":"gpt-5.4-mini","tools":[],"scopes":["doc.read"]},{"name":"summariser","description":"Summarise a document, or a part of one — what it says, in the order it says it, with citations. Use when the user asks what a document is about, for an overview, or for the key points. For answering a specific question from documents, use rag-query instead.","model":"gpt-5.6-luna","tools":["doc.list","doc.fetch","doc.search_raw"],"scopes":["doc.read"]},{"name":"table_analyst","description":"Answer a question about a table — trends, comparisons, aggregates, calculations. Use when the question turns on what tabular data means. For repairing a table that OCR mangled, use postprocessor instead.","model":"gpt-5.4","tools":[],"scopes":["data.read"]}],"tools":[{"name":"doc.chunk","description":"Split a parsed document into semantically bounded, type-tagged chunks.","scopes":["doc.read"],"service":null,"reads":["parsed_document"],"writes":["chunks"]},{"name":"doc.compare_retrieve","description":"Retrieve each side of a comparison separately, with its own budget.","scopes":["doc.read"],"service":"opensearch","reads":[],"writes":["comparison_evidence"]},{"name":"doc.completeness_score","description":"The final band: completeness from the agent's aspect verdicts,\ngroundedness carried through from ``retrieval_score``, combined by fixed\nweights — never re-judged here.","scopes":["doc.read"],"service":null,"reads":[],"writes":[]},{"name":"doc.embed","description":"Compute an embedding for each chunk with text, and return the full chunk list.","scopes":["doc.read"],"service":"embedding","reads":["chunks"],"writes":["chunks"]},{"name":"doc.extract_images","description":"Extract embedded pictures, PPTX shape-fill swatches, and whole-slide\nthumbnails as image chunks.","scopes":["doc.read","doc.write"],"service":"storage","reads":["parsed_document","chunks","doc_id","file_path"],"writes":["chunks"]},{"name":"doc.fetch","description":"Read one indexed document back, in the order it was written.","scopes":["doc.read"],"service":"opensearch","reads":[],"writes":["document"]},{"name":"doc.index","description":"Bulk-write chunks to the search index.","scopes":["doc.write"],"service":"opensearch","reads":["chunks","doc_class"],"writes":["index_result"]},{"name":"doc.list","description":"The documents this tenant can reach, newest first.","scopes":["doc.read"],"service":"opensearch","reads":[],"writes":["corpus"]},{"name":"doc.mm_embed","description":"Compute a multimodal embedding for each image chunk.","scopes":["doc.read"],"service":"mm_embedding","reads":["chunks"],"writes":["chunks"]},{"name":"doc.parse","description":"Convert a document into a structured representation with element tagging.","scopes":["doc.read"],"service":null,"reads":[],"writes":["parsed_document"]},{"name":"doc.retrieval_score","description":"Groundedness of the evidence a run collected, from reranker scores alone.","scopes":["doc.read"],"service":null,"reads":[],"writes":[]},{"name":"doc.search_raw","description":"Retrieve ranked chunks matching a query.","scopes":["doc.read"],"service":"opensearch","reads":[],"writes":["search_hits"]},{"name":"gen.docx","description":"Render a Markdown document as a .docx.","scopes":["doc.write"],"service":null,"reads":["draft_markdown"],"writes":["docx_path"]},{"name":"io.postgres_store","description":"Insert rows into an existing table, in batches, inside one transaction.","scopes":["data.write"],"service":"postgres","reads":[],"writes":["stored_rows"]},{"name":"io.s3_upload","description":"Upload a file to S3 and return its URI.","scopes":["file.write"],"service":"s3","reads":["xlsx_path"],"writes":["s3_uri"]},{"name":"struct.excel","description":"Write tables to an .xlsx workbook, one worksheet per table.","scopes":["doc.write"],"service":null,"reads":["clean_tables"],"writes":["xlsx_path"]},{"name":"struct.ocr","description":"Extract text and table structure from a scanned document.","scopes":["doc.read"],"service":"textract","reads":[],"writes":["raw_tables"]},{"name":"struct.preprocess","description":"Correct page rotation and skew in a scanned PDF.","scopes":["doc.read","doc.write"],"service":null,"reads":[],"writes":["preprocessed_pdf"]}]}