From 1ebc2372dec2fc07b9a7a470bd39efb6a8a83d2b Mon Sep 17 00:00:00 2001 From: a2a-platform Date: Sat, 27 Jun 2026 01:06:34 +0000 Subject: [PATCH] deploy --- README.md | 11 + a2a.yaml | 13 + agent.py | 732 +++++++++++++++ openapi.json | 2299 ++++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 7 + 5 files changed, 3062 insertions(+) create mode 100644 README.md create mode 100644 a2a.yaml create mode 100644 agent.py create mode 100644 openapi.json create mode 100644 requirements.txt diff --git a/README.md b/README.md new file mode 100644 index 0000000..b509139 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# pinecone-openapi-agent + +Generated A2APack agent for Pinecone Data Plane API. + +- Source OpenAPI: https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml +- Generated operations: 16 +- Main skill: `auto` +- Routing mode: direct operation skills + +The generated code is intentionally editable. Tune prompts, operation +grouping, auth names, and safety policy before publishing serious agents. diff --git a/a2a.yaml b/a2a.yaml new file mode 100644 index 0000000..967946a --- /dev/null +++ b/a2a.yaml @@ -0,0 +1,13 @@ +name: pinecone-openapi-agent +version: 2025-04 +entrypoint: agent:PineconeOpenapiAgent +description: Vector database data-plane API for records, vectors, namespaces, search, + and fetch operations. +runtime: + resources: + cpu: 200m + memory: 512Mi + egress: + allow_hosts: + - '{index_host}' + deny_internet_by_default: true diff --git a/agent.py b/agent.py new file mode 100644 index 0000000..1c1965c --- /dev/null +++ b/agent.py @@ -0,0 +1,732 @@ +from __future__ import annotations + +import base64 +import json +import re +from pathlib import Path +from typing import Any + +import httpx +from a2a_pack.deepagents import create_a2a_deep_agent +from langchain_core.messages import BaseMessage +from langchain_core.tools import StructuredTool +from pydantic import BaseModel, Field + +from a2a_pack import ( + A2AAgent, + ConsumerSetup, + ConsumerSetupField, + ConsumerSetupMissing, + EgressPolicy, + LLMProvisioning, + Pricing, + Resources, + RunContext, + skill, +) + + +DEFAULT_BASE_URL = "https://{index_host}" +OPERATIONS = json.loads("{\n \"cancel_bulk_import\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Cancel an import operation if it is not yet finished. It has no effect if the operation is already finished.\\n\\nFor guidance and examples, see [Import data](https://docs.pinecone.io/guides/index-data/import-data).\",\n \"destructive\": true,\n \"method\": \"DELETE\",\n \"operation_id\": \"cancel_bulk_import\",\n \"parameters\": [\n {\n \"description\": \"Unique identifier for the import operation.\",\n \"in\": \"path\",\n \"name\": \"id\",\n \"required\": true,\n \"schema\": {\n \"maxLength\": 1000,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/bulk/imports/{id}\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"cancel_bulk_import\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Cancel an import\",\n \"tags\": [\n \"Bulk Operations\"\n ]\n },\n \"delete_namespace\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Delete a namespace from a serverless index. Deleting a namespace is irreversible; all data in the namespace is permanently deleted.\\n\\nFor guidance and examples, see [Manage namespaces](https://docs.pinecone.io/guides/manage-data/manage-namespaces).\\n\\n**Note:** This operation is not supported for pod-based indexes.\",\n \"destructive\": true,\n \"method\": \"DELETE\",\n \"operation_id\": \"delete_namespace\",\n \"parameters\": [\n {\n \"description\": \"The namespace to delete\",\n \"in\": \"path\",\n \"name\": \"namespace\",\n \"required\": true,\n \"schema\": {\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/namespaces/{namespace}\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"delete_namespace\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Delete a namespace\",\n \"tags\": [\n \"Namespace Operations\"\n ]\n },\n \"delete_vectors\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Delete vectors by id from a single namespace.\\n\\nFor guidance and examples, see [Delete data](https://docs.pinecone.io/guides/manage-data/delete-data).\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"delete_vectors\",\n \"parameters\": [],\n \"path\": \"/vectors/delete\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/DeleteRequest\"\n },\n \"security\": null,\n \"skill_name\": \"delete_vectors\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Delete vectors\",\n \"tags\": [\n \"Vector Operations\"\n ]\n },\n \"describe_bulk_import\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Return details of a specific import operation.\\n\\nFor guidance and examples, see [Import data](https://docs.pinecone.io/guides/index-data/import-data).\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"describe_bulk_import\",\n \"parameters\": [\n {\n \"description\": \"Unique identifier for the import operation.\",\n \"in\": \"path\",\n \"name\": \"id\",\n \"required\": true,\n \"schema\": {\n \"maxLength\": 1000,\n \"minLength\": 1,\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/bulk/imports/{id}\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"describe_bulk_import\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Describe an import\",\n \"tags\": [\n \"Bulk Operations\"\n ]\n },\n \"describe_index_stats\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Return statistics about the contents of an index, including the vector count per namespace, the number of dimensions, and the index fullness.\\n\\nServerless indexes scale automatically as needed, so index fullness is relevant only for pod-based indexes.\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"describe_index_stats\",\n \"parameters\": [],\n \"path\": \"/describe_index_stats\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/DescribeIndexStatsRequest\"\n },\n \"security\": null,\n \"skill_name\": \"describe_index_stats\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Get index stats\",\n \"tags\": [\n \"Vector Operations\"\n ]\n },\n \"describe_namespace\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Describe a namespace in a serverless index, including the total number of vectors in the namespace.\\n\\nFor guidance and examples, see [Manage namespaces](https://docs.pinecone.io/guides/manage-data/manage-namespaces).\\n\\n**Note:** This operation is not supported for pod-based indexes.\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"describe_namespace\",\n \"parameters\": [\n {\n \"description\": \"The namespace to describe\",\n \"in\": \"path\",\n \"name\": \"namespace\",\n \"required\": true,\n \"schema\": {\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/namespaces/{namespace}\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"describe_namespace\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Describe a namespace\",\n \"tags\": [\n \"Namespace Operations\"\n ]\n },\n \"fetch_vectors\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Look up and return vectors by ID from a single namespace. The returned vectors include the vector data and/or metadata.\\n\\nFor on-demand indexes, since vector values are retrieved from object storage, fetch operations may have increased latency. If you only need metadata or IDs, consider using the query operation with `includeValues` set to `false` instead.\\n\\nFor guidance and examples, see [Fetch data](https://docs.pinecone.io/guides/manage-data/fetch-data).\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"fetch_vectors\",\n \"parameters\": [\n {\n \"description\": \"The vector IDs to fetch. Does not accept values containing spaces.\",\n \"in\": \"query\",\n \"name\": \"ids\",\n \"required\": true,\n \"schema\": {\n \"items\": {\n \"type\": \"string\"\n },\n \"type\": \"array\"\n }\n },\n {\n \"description\": \"\",\n \"in\": \"query\",\n \"name\": \"namespace\",\n \"required\": false,\n \"schema\": {\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/vectors/fetch\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"fetch_vectors\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Fetch vectors\",\n \"tags\": [\n \"Vector Operations\"\n ]\n },\n \"list_bulk_imports\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"List all recent and ongoing import operations.\\n\\nBy default, `list_imports` returns up to 100 imports per page. If the `limit` parameter is set, `list` returns up to that number of imports instead. Whenever there are additional IDs to return, the response also includes a `pagination_token` that you can use to get the next batch of imports. When the response does not include a `pagination_token`, there are no more imports to return.\\n\\nFor guidance and examples, see [Import data](https://docs.pinecone.io/guides/index-data/import-data).\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"list_bulk_imports\",\n \"parameters\": [\n {\n \"description\": \"Max number of operations to return per page.\",\n \"in\": \"query\",\n \"name\": \"limit\",\n \"required\": false,\n \"schema\": {\n \"default\": \"100\",\n \"format\": \"int32\",\n \"maximum\": 100,\n \"minimum\": 1,\n \"type\": \"integer\"\n }\n },\n {\n \"description\": \"Pagination token to continue a previous listing operation.\",\n \"in\": \"query\",\n \"name\": \"paginationToken\",\n \"required\": false,\n \"schema\": {\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/bulk/imports\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"list_bulk_imports\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"List imports\",\n \"tags\": [\n \"Bulk Operations\"\n ]\n },\n \"list_namespaces_operation\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"List all namespaces in a serverless index.\\n\\nUp to 100 namespaces are returned at a time by default, in sorted order (bitwise \\u201cC\\u201d collation). If the `limit` parameter is set, up to that number of namespaces are returned instead. Whenever there are additional namespaces to return, the response also includes a `pagination_token` that you can use to get the next batch of namespaces. When the response does not include a `pagination_token`, there are no more namespaces to return.\\n\\nFor guidance and examples, see [Manage namespaces](https://docs.pinecone.io/guides/manage-data/manage-namespaces).\\n\\n**Note:** This operation is not supported for pod-based indexes.\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"list_namespaces_operation\",\n \"parameters\": [\n {\n \"description\": \"Max number namespaces to return per page.\",\n \"in\": \"query\",\n \"name\": \"limit\",\n \"required\": false,\n \"schema\": {\n \"format\": \"int32\",\n \"type\": \"integer\"\n }\n },\n {\n \"description\": \"Pagination token to continue a previous listing operation.\",\n \"in\": \"query\",\n \"name\": \"paginationToken\",\n \"required\": false,\n \"schema\": {\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/namespaces\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"list_namespaces_operation\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"List namespaces\",\n \"tags\": [\n \"Namespace Operations\"\n ]\n },\n \"list_vectors\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"List the IDs of vectors in a single namespace of a serverless index. An optional prefix can be passed to limit the results to IDs with a common prefix.\\n\\nReturns up to 100 IDs at a time by default in sorted order (bitwise \\\"C\\\" collation). If the `limit` parameter is set, `list` returns up to that number of IDs instead. Whenever there are additional IDs to return, the response also includes a `pagination_token` that you can use to get the next batch of IDs. When the response does not include a `pagination_token`, there are no more IDs to return.\\n\\nFor guidance and examples, see [List record IDs](https://docs.pinecone.io/guides/manage-data/list-record-ids).\\n\\n**Note:** `list` is supported only for serverless indexes.\",\n \"destructive\": false,\n \"method\": \"GET\",\n \"operation_id\": \"list_vectors\",\n \"parameters\": [\n {\n \"description\": \"The vector IDs to fetch. Does not accept values containing spaces.\",\n \"in\": \"query\",\n \"name\": \"prefix\",\n \"required\": false,\n \"schema\": {\n \"type\": \"string\"\n }\n },\n {\n \"description\": \"Max number of IDs to return per page.\",\n \"in\": \"query\",\n \"name\": \"limit\",\n \"required\": false,\n \"schema\": {\n \"default\": \"100\",\n \"format\": \"int64\",\n \"type\": \"integer\"\n }\n },\n {\n \"description\": \"Pagination token to continue a previous listing operation.\",\n \"in\": \"query\",\n \"name\": \"paginationToken\",\n \"required\": false,\n \"schema\": {\n \"type\": \"string\"\n }\n },\n {\n \"description\": \"\",\n \"in\": \"query\",\n \"name\": \"namespace\",\n \"required\": false,\n \"schema\": {\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/vectors/list\",\n \"request_body\": null,\n \"security\": null,\n \"skill_name\": \"list_vectors\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"List vector IDs\",\n \"tags\": [\n \"Vector Operations\"\n ]\n },\n \"query_vectors\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Search a namespace using a query vector. It retrieves the ids of the most similar items in a namespace, along with their similarity scores.\\n\\nFor guidance, examples, and limits, see [Search](https://docs.pinecone.io/guides/search/search-overview).\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"query_vectors\",\n \"parameters\": [],\n \"path\": \"/query\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/QueryRequest\"\n },\n \"security\": null,\n \"skill_name\": \"query_vectors\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Search with a vector\",\n \"tags\": [\n \"Vector Operations\"\n ]\n },\n \"search_records_namespace\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Search a namespace with a query text, query vector, or record ID and return the most similar records, along with their similarity scores. Optionally, rerank the initial results based on their relevance to the query. \\n\\nSearching with text is supported only for [indexes with integrated embedding](https://docs.pinecone.io/guides/indexes/create-an-index#integrated-embedding). Searching with a query vector or record ID is supported for all indexes. \\n\\nFor guidance, examples, and limits, see [Search](https://docs.pinecone.io/guides/search/search-overview).\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"search_records_namespace\",\n \"parameters\": [\n {\n \"description\": \"The namespace to search.\",\n \"in\": \"path\",\n \"name\": \"namespace\",\n \"required\": true,\n \"schema\": {\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/records/namespaces/{namespace}/search\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/SearchRecordsRequest\"\n },\n \"security\": null,\n \"skill_name\": \"search_records_namespace\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Search with text\",\n \"tags\": [\n \"Vector Operations\"\n ]\n },\n \"start_bulk_import\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Start an asynchronous import of vectors from object storage into an index.\\n\\nFor guidance and examples, see [Import data](https://docs.pinecone.io/guides/index-data/import-data).\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"start_bulk_import\",\n \"parameters\": [],\n \"path\": \"/bulk/imports\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/StartImportRequest\"\n },\n \"security\": null,\n \"skill_name\": \"start_bulk_import\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Start import\",\n \"tags\": [\n \"Bulk Operations\"\n ]\n },\n \"update_vector\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Update a vector in a namespace. If a value is included, it will overwrite the previous value. If a `set_metadata` is included, the values of the fields specified in it will be added or overwrite the previous value.\\n\\nFor guidance and examples, see [Update data](https://docs.pinecone.io/guides/manage-data/update-data).\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"update_vector\",\n \"parameters\": [],\n \"path\": \"/vectors/update\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/UpdateRequest\"\n },\n \"security\": null,\n \"skill_name\": \"update_vector\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Update a vector\",\n \"tags\": [\n \"Vector Operations\"\n ]\n },\n \"upsert_records_namespace\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Upsert text into a namespace. Pinecone converts the text to vectors automatically using the hosted embedding model associated with the index.\\n\\nUpserting text is supported only for [indexes with integrated embedding](https://docs.pinecone.io/guides/index-data/create-an-index#embedding-models).\\n\\nFor guidance, examples, and limits, see [Upsert data](https://docs.pinecone.io/guides/index-data/upsert-data).\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"upsert_records_namespace\",\n \"parameters\": [\n {\n \"description\": \"The namespace to upsert records into.\",\n \"in\": \"path\",\n \"name\": \"namespace\",\n \"required\": true,\n \"schema\": {\n \"type\": \"string\"\n }\n }\n ],\n \"path\": \"/records/namespaces/{namespace}/upsert\",\n \"request_body\": {\n \"items\": {\n \"$ref\": \"#/components/schemas/UpsertRecord\"\n },\n \"type\": \"array\"\n },\n \"security\": null,\n \"skill_name\": \"upsert_records_namespace\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Upsert text\",\n \"tags\": [\n \"Vector Operations\"\n ]\n },\n \"upsert_vectors\": {\n \"base_url\": \"https://{index_host}\",\n \"base_url_field\": \"OPENAPI_BASE_URL\",\n \"description\": \"Upsert vectors into a namespace. If a new value is upserted for an existing vector ID, it will overwrite the previous value.\\n\\nFor guidance, examples, and limits, see [Upsert data](https://docs.pinecone.io/guides/index-data/upsert-data).\",\n \"destructive\": true,\n \"method\": \"POST\",\n \"operation_id\": \"upsert_vectors\",\n \"parameters\": [],\n \"path\": \"/vectors/upsert\",\n \"request_body\": {\n \"$ref\": \"#/components/schemas/UpsertRequest\"\n },\n \"security\": null,\n \"skill_name\": \"upsert_vectors\",\n \"source_index\": 1,\n \"source_openapi_url\": \"https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml\",\n \"source_title\": \"Pinecone Data Plane API\",\n \"summary\": \"Upsert vectors\",\n \"tags\": [\n \"Vector Operations\"\n ]\n }\n}") +OPERATION_GROUPS = json.loads("[]") +ROOT_SECURITY = json.loads("[\n {\n \"ApiKeyAuth\": []\n }\n]") +SECURITY_SCHEMES = json.loads("{\n \"ApiKeyAuth\": {\n \"description\": \"An API Key is required to call Pinecone APIs. Get yours from the [console](https://app.pinecone.io/).\",\n \"in\": \"header\",\n \"name\": \"Api-Key\",\n \"type\": \"apiKey\"\n }\n}") +SECURITY_FIELDS = json.loads("{\n \"ApiKeyAuth\": {\n \"field\": \"API_KEY\",\n \"kind\": \"apiKey\",\n \"location\": \"header\",\n \"name\": \"Api-Key\"\n }\n}") +PATH_PARAMETER_RE = re.compile(r"{([^}/]+)}") +SOURCE_ROOT = Path(globals().get("__file__", "agent.py")).resolve().parent +SOURCE_SKILLS_DIR = SOURCE_ROOT / "skills" +RUNTIME_SKILLS_DIR = ".deepagents/openapi-skills/" + + +class OperationInput(BaseModel): + parameters: dict[str, Any] = Field( + default_factory=dict, + description="Path, query, header, and cookie parameters keyed by OpenAPI parameter name.", + ) + body: Any | None = Field(default=None, description="JSON request body, when the operation accepts one.") + + +class PineconeOpenapiAgent(A2AAgent): + name = "pinecone-openapi-agent" + description = "Vector database data-plane API for records, vectors, namespaces, search, and fetch operations." + version = "2025-04" + consumer_setup = ConsumerSetup.from_fields( + ConsumerSetupField.config("OPENAPI_BASE_URL", label="API base URL", description="Override the default API server (https://{index_host}).", required=False, input_type="url"), + ConsumerSetupField.secret("API_KEY", label="ApiKeyAuth API key", description="An API Key is required to call Pinecone APIs. Get yours from the [console](https://app.pinecone.io/).", required=True), + ) + llm_provisioning = LLMProvisioning.PLATFORM + pricing = Pricing( + price_per_call_usd=0.0, + caller_pays_llm=True, + notes="Uses the caller's saved LLM credential through ctx.llm.", + ) + resources = Resources(cpu="200m", memory="512Mi") + egress = EgressPolicy( + allow_hosts=('{index_host}',), + deny_internet_by_default=True, + ) + tools_used = ("openapi", "deepagents") + capabilities = { + "openapi_auto_agent": { + "operation_count": len(OPERATIONS), + "default_base_url": DEFAULT_BASE_URL, + "source_openapi_url": 'https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml', + "source_openapi_urls": ['https://raw.githubusercontent.com/pinecone-io/pinecone-api/main/2025-04/db_data_2025-04.oas.yaml'], + "server_urls": ['https://{index_host}'], + "regenerable": True, + "security_schemes": list(SECURITY_SCHEMES), + } + } + + @skill( + name="auto", + description="Use the OpenAPI service to complete a natural-language goal.", + tags=("openapi", "auto"), + timeout_seconds=900, + ) + async def auto(self, ctx: RunContext, goal: str) -> dict[str, Any]: + creds = ctx.llm + if not creds.api_key: + return { + "error": "llm_credentials_missing", + "final": ( + "LLM key required. Add an LLM credential in Settings > " + "LLM credentials before running this agent." + ), + "messages": [], + } + graph = create_a2a_deep_agent( + ctx, + creds=creds, + tools=self._operation_tools(ctx), + system_prompt=self._system_prompt(), + ) + result = await graph.ainvoke({"messages": [{"role": "user", "content": goal}]}) + messages = result.get("messages", []) if isinstance(result, dict) else [] + final = _message_text(messages[-1]) if messages else result + return { + "final": final, + "messages": [_message_to_dict(message) for message in messages[-8:]], + } + + @skill( + name="list_bulk_imports", + description="GET /bulk/imports - List imports", + tags=('Bulk Operations',), + timeout_seconds=60, + ) + async def list_bulk_imports( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "list_bulk_imports", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="start_bulk_import", + description="POST /bulk/imports - Start import", + tags=('Bulk Operations',), + timeout_seconds=120, + ) + async def start_bulk_import( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "start_bulk_import", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="describe_bulk_import", + description="GET /bulk/imports/{id} - Describe an import", + tags=('Bulk Operations',), + timeout_seconds=60, + ) + async def describe_bulk_import( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "describe_bulk_import", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="cancel_bulk_import", + description="DELETE /bulk/imports/{id} - Cancel an import", + tags=('Bulk Operations',), + timeout_seconds=120, + ) + async def cancel_bulk_import( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "cancel_bulk_import", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="describe_index_stats", + description="POST /describe_index_stats - Get index stats", + tags=('Vector Operations',), + timeout_seconds=120, + ) + async def describe_index_stats( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "describe_index_stats", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="query_vectors", + description="POST /query - Search with a vector", + tags=('Vector Operations',), + timeout_seconds=120, + ) + async def query_vectors( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "query_vectors", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="delete_vectors", + description="POST /vectors/delete - Delete vectors", + tags=('Vector Operations',), + timeout_seconds=120, + ) + async def delete_vectors( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "delete_vectors", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="fetch_vectors", + description="GET /vectors/fetch - Fetch vectors", + tags=('Vector Operations',), + timeout_seconds=60, + ) + async def fetch_vectors( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "fetch_vectors", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="list_vectors", + description="GET /vectors/list - List vector IDs", + tags=('Vector Operations',), + timeout_seconds=60, + ) + async def list_vectors( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "list_vectors", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="update_vector", + description="POST /vectors/update - Update a vector", + tags=('Vector Operations',), + timeout_seconds=120, + ) + async def update_vector( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "update_vector", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="upsert_vectors", + description="POST /vectors/upsert - Upsert vectors", + tags=('Vector Operations',), + timeout_seconds=120, + ) + async def upsert_vectors( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "upsert_vectors", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="list_namespaces_operation", + description="GET /namespaces - List namespaces", + tags=('Namespace Operations',), + timeout_seconds=60, + ) + async def list_namespaces_operation( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "list_namespaces_operation", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="describe_namespace", + description="GET /namespaces/{namespace} - Describe a namespace", + tags=('Namespace Operations',), + timeout_seconds=60, + ) + async def describe_namespace( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "describe_namespace", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="delete_namespace", + description="DELETE /namespaces/{namespace} - Delete a namespace", + tags=('Namespace Operations',), + timeout_seconds=120, + ) + async def delete_namespace( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "delete_namespace", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="upsert_records_namespace", + description="POST /records/namespaces/{namespace}/upsert - Upsert text", + tags=('Vector Operations',), + timeout_seconds=120, + ) + async def upsert_records_namespace( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "upsert_records_namespace", + parameters=parameters or {}, + body=body, + ) + + @skill( + name="search_records_namespace", + description="POST /records/namespaces/{namespace}/search - Search with text", + tags=('Vector Operations',), + timeout_seconds=120, + ) + async def search_records_namespace( + self, + ctx: RunContext, + parameters: dict[str, Any] | None = None, + body: Any | None = None, + ) -> dict[str, Any]: + return await self._request( + ctx, + "search_records_namespace", + parameters=parameters or {}, + body=body, + ) + + def _operation_subagents(self, ctx: RunContext, skills_root: str) -> list[dict[str, Any]]: + subagents: list[dict[str, Any]] = [] + for group in OPERATION_GROUPS: + skill_path = ( + f"{skills_root}{group['skill_dir']}/" + if skills_root + else "" + ) + subagent = { + "name": group["subagent_name"], + "description": group["description"], + "system_prompt": self._subagent_prompt(group), + "tools": self._operation_tools(ctx, set(group["operation_ids"])), + } + if skill_path: + subagent["skills"] = [skill_path] + subagents.append(subagent) + return subagents + + def _operation_tools( + self, + ctx: RunContext, + operation_ids: set[str] | None = None, + ) -> list[StructuredTool]: + tools: list[StructuredTool] = [] + for operation_id, operation in OPERATIONS.items(): + if operation_ids is not None and operation_id not in operation_ids: + continue + async def call( + parameters: dict[str, Any] | None = None, + body: Any | None = None, + *, + _operation_id: str = operation_id, + ) -> dict[str, Any]: + return await self._request( + ctx, + _operation_id, + parameters=parameters or {}, + body=body, + ) + + tools.append( + StructuredTool.from_function( + coroutine=call, + name=operation["skill_name"], + description=self._tool_description(operation), + args_schema=OperationInput, + ) + ) + return tools + + def _system_prompt(self) -> str: + if OPERATION_GROUPS: + lines = [ + "You coordinate route-specific OpenAPI subagents.", + "Delegate API work to the matching subagent with the task tool.", + "Do not invent API responses; ask subagents to call their tools for real results.", + "If a subagent reports missing consumer setup, tell the user which setup field is required.", + "If a subagent reports that the generated OpenAPI agent may be stale, ask whether the user wants to refresh it from the latest OpenAPI spec.", + "", + "Available route groups:", + ] + for group in OPERATION_GROUPS: + lines.append( + f"- {group['subagent_name']}: {group['description']}" + ) + return "\n".join(lines) + lines = [ + "You operate an API through generated OpenAPI tools.", + "Call tools to get real results. Do not invent API responses.", + "For write, update, or delete operations, explain the intended action before calling the tool.", + "If an operation reports missing consumer setup, tell the user which setup field is required.", + "If an operation returns 404, 405, 410, or a schema/validation error that suggests the live API no longer matches these tools, tell the user this generated agent may need to be refreshed from the latest OpenAPI spec and ask whether they want to refresh it.", + "", + "Available operations:", + ] + for operation in OPERATIONS.values(): + marker = "WRITE" if operation.get("destructive") else "READ" + lines.append( + f"- {operation['skill_name']}: {marker} {operation['method']} {operation['path']} — {operation['summary']}" + ) + return "\n".join(lines) + + def _subagent_prompt(self, group: dict[str, Any]) -> str: + lines = [ + "You operate one route group from a generated OpenAPI API.", + "Use the available operation tools to make real API calls. Do not invent API responses.", + "Read the route group's SKILL.md when it applies; it lists every route you cover.", + "For write, update, or delete operations, explain the intended action before calling the tool.", + "If an operation reports missing consumer setup, return the exact setup field name.", + "If an operation returns 404, 405, 410, or a schema/validation error that suggests the live API no longer matches these tools, say the generated agent may need to be refreshed from the latest OpenAPI spec.", + "", + f"Route group: {group['label']}", + f"Common prefix: {group.get('common_prefix') or '/'}", + "Available operation tools:", + ] + for operation_id in group["operation_ids"]: + operation = OPERATIONS[operation_id] + marker = "WRITE" if operation.get("destructive") else "READ" + lines.append( + f"- {operation['skill_name']}: {marker} {operation['method']} {operation['path']} - {operation['summary']}" + ) + return "\n".join(lines) + + def _tool_description(self, operation: dict[str, Any]) -> str: + parts = [ + f"{operation['method']} {operation['path']}", + str(operation.get("description") or operation.get("summary") or ""), + ] + if operation.get("parameters"): + parts.append( + "Parameters: " + + ", ".join( + f"{p['name']} in {p['in']}{' required' if p.get('required') else ''}" + for p in operation["parameters"] + ) + ) + if operation.get("request_body") is not None: + parts.append("Accepts a JSON request body.") + return "\n".join(part for part in parts if part) + + async def _request( + self, + ctx: RunContext, + operation_id: str, + *, + parameters: dict[str, Any], + body: Any | None, + ) -> dict[str, Any]: + operation = OPERATIONS[operation_id] + default_base_url = str(operation.get("base_url") or DEFAULT_BASE_URL).rstrip("/") + base_url_field = str(operation.get("base_url_field") or "OPENAPI_BASE_URL") + base_url = str(ctx.consumer_config(base_url_field, default_base_url) or default_base_url).rstrip("/") + url, query, headers = self._request_parts(ctx, operation, parameters) + request_kwargs: dict[str, Any] = { + "params": query, + "headers": headers, + } + if body is not None: + if isinstance(body, (bytes, bytearray)): + body = body.decode("utf-8", errors="replace") + if isinstance(body, str): + stripped = body.strip() + if stripped and stripped[0] in "{[": + try: + body = json.loads(stripped) + except ValueError: + pass + request_kwargs["json"] = body + async with httpx.AsyncClient(timeout=60.0, follow_redirects=True) as client: + response = await client.request( + operation["method"], + f"{base_url}{url}", + **request_kwargs, + ) + content_type = response.headers.get("content-type", "") + try: + payload: Any = response.json() if "json" in content_type else response.text + except ValueError: + payload = response.text + if response.status_code >= 400: + out = { + "ok": False, + "status_code": response.status_code, + "operation_id": operation_id, + "error": payload, + } + if response.status_code in {404, 405, 410, 422}: + out["stale_openapi_hint"] = ( + "This generated OpenAPI agent may be stale. Ask the user " + "whether they want to refresh it from the latest OpenAPI spec." + ) + return out + return { + "ok": True, + "status_code": response.status_code, + "operation_id": operation_id, + "result": payload, + } + + def _request_parts( + self, + ctx: RunContext, + operation: dict[str, Any], + parameters: dict[str, Any], + ) -> tuple[str, dict[str, Any], dict[str, str]]: + path = operation["path"] + query: dict[str, Any] = {} + headers: dict[str, str] = {} + cookies: dict[str, Any] = {} + for param in operation.get("parameters") or []: + name = param["name"] + if name not in parameters: + if param.get("required"): + raise ValueError(f"missing required parameter {name!r}") + continue + value = parameters[name] + location = param["in"] + if location == "path": + path = path.replace("{" + name + "}", str(value)) + elif location == "query": + query[name] = value + elif location == "header": + headers[name] = str(value) + elif location == "cookie": + cookies[name] = value + unresolved = PATH_PARAMETER_RE.findall(path) + if unresolved: + missing = ", ".join(sorted(set(unresolved))) + raise ValueError("missing required path parameter(s): " + missing) + if cookies: + headers["cookie"] = "; ".join(f"{key}={value}" for key, value in cookies.items()) + auth_headers, auth_query = self._auth_for_operation(ctx, operation) + headers.update(auth_headers) + query.update(auth_query) + return path, query, headers + + def _auth_for_operation(self, ctx: RunContext, operation: dict[str, Any]) -> tuple[dict[str, str], dict[str, Any]]: + requirements = operation.get("security") + if requirements is None: + requirements = ROOT_SECURITY + if requirements == []: + return {}, {} + missing: list[str] = [] + for requirement in requirements or []: + if not isinstance(requirement, dict) or not requirement: + return {}, {} + headers: dict[str, str] = {} + query: dict[str, Any] = {} + ok = True + for scheme_name in requirement: + mapping = SECURITY_FIELDS.get(scheme_name) or {} + secret_name = mapping.get("field") + value = _consumer_secret_optional(ctx, secret_name) if secret_name else "" + if not value: + ok = False + if secret_name: + missing.append(secret_name) + continue + kind = mapping.get("kind") + if kind == "apiKey": + prefix = mapping.get("prefix") or "" + sent_value = f"{prefix}{value}" + if mapping.get("location") == "query": + query[mapping.get("name") or scheme_name] = sent_value + else: + headers[mapping.get("name") or scheme_name] = sent_value + elif kind in {"http", "oauth2"}: + scheme = mapping.get("scheme") or "Bearer" + if scheme.lower() == "basic": + token = base64.b64encode(value.encode("utf-8")).decode("ascii") + headers["authorization"] = f"Basic {token}" + else: + headers["authorization"] = f"{scheme} {value}" + else: + ok = False + if ok: + return headers, query + if missing: + raise ConsumerSetupMissing( + "operation requires consumer setup secret(s): " + + ", ".join(sorted(set(missing))) + ) + return {}, {} + + +def _consumer_secret_optional(ctx: RunContext, name: str | None) -> str: + if not name: + return "" + try: + return ctx.consumer_secret(name) + except ConsumerSetupMissing: + return "" + + +def _runtime_skills_root(ctx: RunContext) -> str: + workspace = getattr(ctx, "_workspace", None) + prefixes = tuple(getattr(workspace, "write_prefixes", ()) or ()) + if not prefixes: + outputs_prefix = getattr(workspace, "outputs_prefix", None) + prefixes = (outputs_prefix or "outputs/",) + prefix = str(prefixes[0]).strip("/") + return f"/{prefix}/{RUNTIME_SKILLS_DIR}" if prefix else f"/{RUNTIME_SKILLS_DIR}" + + +def _seed_runtime_skills(backend: Any, ctx: RunContext) -> str: + if not SOURCE_SKILLS_DIR.exists(): + return "" + runtime_root = _runtime_skills_root(ctx) + uploads: list[tuple[str, bytes]] = [] + for path in SOURCE_SKILLS_DIR.rglob("*"): + if not path.is_file(): + continue + rel = path.relative_to(SOURCE_SKILLS_DIR).as_posix() + uploads.append((runtime_root + rel, path.read_bytes())) + if not uploads: + return "" + backend.upload_files(uploads) + return runtime_root + + +def _message_text(message: Any) -> Any: + content = getattr(message, "content", message) + return content + + +def _message_to_dict(message: Any) -> dict[str, Any]: + if isinstance(message, BaseMessage): + return message.model_dump(mode="json") + if hasattr(message, "model_dump"): + return message.model_dump(mode="json") + if isinstance(message, dict): + return message + return {"content": str(message)} + + +agent = PineconeOpenapiAgent() diff --git a/openapi.json b/openapi.json new file mode 100644 index 0000000..e213e3b --- /dev/null +++ b/openapi.json @@ -0,0 +1,2299 @@ +{ + "components": { + "schemas": { + "CancelImportResponse": { + "description": "The response for the `cancel_import` operation.", + "type": "object" + }, + "DeleteRequest": { + "description": "The request for the `delete` operation.", + "properties": { + "deleteAll": { + "default": "false", + "description": "This indicates that all vectors in the index namespace should be deleted.", + "example": false, + "type": "boolean" + }, + "filter": { + "description": "If specified, the metadata filter here will be used to select the vectors to delete. This is mutually exclusive with specifying ids to delete in the ids param or using delete_all=True. See [Delete data](https://docs.pinecone.io/guides/manage-data/delete-data#delete-records-by-metadata).", + "type": "object" + }, + "ids": { + "description": "Vectors to delete.", + "example": [ + "id-0", + "id-1" + ], + "items": { + "type": "string" + }, + "maxLength": 1000, + "minLength": 1, + "type": "array" + }, + "namespace": { + "description": "The namespace to delete vectors from, if applicable.", + "example": "example-namespace", + "type": "string" + } + }, + "type": "object" + }, + "DeleteResponse": { + "description": "The response for the `delete` operation.", + "type": "object" + }, + "DescribeIndexStatsRequest": { + "description": "The request for the `describe_index_stats` operation.", + "properties": { + "filter": { + "description": "If this parameter is present, the operation only returns statistics for vectors that satisfy the filter. See [Understanding metadata](https://docs.pinecone.io/guides/index-data/indexing-overview#metadata).\n\nServerless indexes do not support filtering `describe_index_stats` by metadata.", + "type": "object" + } + }, + "type": "object" + }, + "EmbedInputs": { + "example": { + "text": "chunk_text" + }, + "type": "object" + }, + "FetchResponse": { + "description": "The response for the `fetch` operation.", + "example": { + "namespace": "example-namespace", + "usage": { + "readUnits": 1 + }, + "vectors": { + "id-1": { + "id": "id-1", + "values": [ + 1.0, + 1.5 + ] + }, + "id-2": { + "id": "id-2", + "values": [ + 2.0, + 1.0 + ] + } + } + }, + "properties": { + "namespace": { + "description": "The namespace of the vectors.", + "example": "example-namespace", + "type": "string" + }, + "usage": { + "$ref": "#/components/schemas/Usage" + }, + "vectors": { + "additionalProperties": { + "$ref": "#/components/schemas/Vector" + }, + "title": "The fetched vectors, in the form of a map between the fetched ids and the fetched vectors", + "type": "object" + } + }, + "type": "object" + }, + "Hit": { + "description": "A record whose vector values are similar to the provided search query.", + "example": { + "_id": "example-record-1", + "_score": 0.9281134605407715, + "fields": { + "data": "your example text", + "more_data": { + "text": "your example text" + } + } + }, + "properties": { + "_id": { + "description": "The record id of the search hit.", + "type": "string" + }, + "_score": { + "description": "The similarity score of the returned record.", + "format": "float", + "type": "number" + }, + "fields": { + "description": "The selected record fields associated with the search hit.", + "type": "object" + } + }, + "required": [ + "_id", + "_score", + "fields" + ], + "type": "object" + }, + "ImportErrorMode": { + "description": "Indicates how to respond to errors during the import process.", + "properties": { + "onError": { + "description": "Indicates how to respond to errors during the import process.", + "enum": [ + "abort", + "continue" + ], + "type": "string" + } + }, + "type": "object" + }, + "ImportModel": { + "description": "The model for an import operation.", + "properties": { + "createdAt": { + "description": "The start time of the import operation.", + "format": "date-time", + "type": "string" + }, + "error": { + "description": "The error message if the import process failed.", + "type": "string" + }, + "finishedAt": { + "description": "The end time of the import operation.", + "format": "date-time", + "type": "string" + }, + "id": { + "description": "Unique identifier for the import operation.", + "example": "101", + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + "percentComplete": { + "description": "The progress made by the operation, as a percentage.", + "example": 42.2, + "format": "float", + "maximum": 100.0, + "minimum": 0.0, + "type": "number" + }, + "recordsImported": { + "description": "The number of records successfully imported.", + "example": 1000000, + "format": "int64", + "type": "integer" + }, + "status": { + "description": "The status of the operation.", + "enum": [ + "Pending", + "InProgress", + "Failed", + "Completed", + "Cancelled" + ], + "example": "Pending", + "type": "string" + }, + "uri": { + "description": "The URI from where the data is imported.", + "type": "string" + } + }, + "type": "object" + }, + "IndexDescription": { + "description": "The response for the `describe_index_stats` operation.", + "example": { + "dimension": 1024, + "index_fullness": 0.4, + "namespaces": { + "": { + "vectorCount": 50000 + }, + "example-namespace-2": { + "vectorCount": 30000 + } + }, + "totalVectorCount": 80000 + }, + "properties": { + "dimension": { + "description": "The dimension of the indexed vectors. Not specified if `sparse` index.", + "example": 1024, + "format": "int64", + "type": "integer" + }, + "indexFullness": { + "description": "The fullness of the index, regardless of whether a metadata filter expression was passed. The granularity of this metric is 10%.\n\nServerless indexes scale automatically as needed, so index fullness is relevant only for pod-based indexes.\n\nThe index fullness result may be inaccurate during pod resizing; to get the status of a pod resizing process, use [`describe_index`](https://docs.pinecone.io/reference/api/2024-10/control-plane/describe_index).", + "example": 0.4, + "format": "float", + "type": "number" + }, + "metric": { + "description": "The metric used to measure similarity.", + "example": "cosine", + "type": "string" + }, + "namespaces": { + "additionalProperties": { + "$ref": "#/components/schemas/NamespaceSummary" + }, + "description": "A mapping for each namespace in the index from the namespace name to a summary of its contents. If a metadata filter expression is present, the summary will reflect only vectors matching that expression.", + "type": "object" + }, + "totalVectorCount": { + "description": "The total number of vectors in the index, regardless of whether a metadata filter expression was passed", + "example": 80000, + "format": "int64", + "type": "integer" + }, + "vectorType": { + "description": "The type of vectors stored in the index.", + "example": "dense", + "type": "string" + } + }, + "type": "object" + }, + "ListImportsResponse": { + "description": "The response for the `list_imports` operation.", + "properties": { + "data": { + "items": { + "$ref": "#/components/schemas/ImportModel" + }, + "type": "array" + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + }, + "type": "object" + }, + "ListItem": { + "properties": { + "id": { + "example": "document1#abb", + "type": "string" + } + }, + "type": "object" + }, + "ListNamespacesResponse": { + "properties": { + "namespaces": { + "description": "The list of namespaces belonging to this index.", + "items": { + "$ref": "#/components/schemas/NamespaceDescription" + }, + "type": "array" + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + } + }, + "type": "object" + }, + "ListResponse": { + "description": "The response for the `list` operation.", + "properties": { + "namespace": { + "description": "The namespace of the vectors.", + "example": "example-namespace", + "type": "string" + }, + "pagination": { + "$ref": "#/components/schemas/Pagination" + }, + "usage": { + "$ref": "#/components/schemas/Usage" + }, + "vectors": { + "example": [ + { + "id": "document1#abb" + }, + { + "id": "document1#abc" + } + ], + "items": { + "$ref": "#/components/schemas/ListItem" + }, + "title": "A list of ids", + "type": "array" + } + }, + "type": "object" + }, + "NamespaceDescription": { + "description": "A description of a namespace, including the name and record count.", + "properties": { + "name": { + "description": "The name of the namespace.", + "example": "example-namespace", + "type": "string" + }, + "record_count": { + "description": "The total amount of records within the namespace.", + "example": 20000, + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, + "NamespaceSummary": { + "description": "A summary of the contents of a namespace.", + "properties": { + "vectorCount": { + "description": "The number of vectors stored in this namespace. Note that updates to this field may lag behind updates to the underlying index and corresponding query results, etc.", + "example": 50000, + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, + "Pagination": { + "properties": { + "next": { + "example": "Tm90aGluZyB0byBzZWUgaGVyZQo=", + "type": "string" + } + }, + "type": "object" + }, + "QueryRequest": { + "description": "The request for the `query` operation.", + "properties": { + "filter": { + "description": "The filter to apply. You can use vector metadata to limit your search. See [Understanding metadata](https://docs.pinecone.io/guides/index-data/indexing-overview#metadata).", + "example": { + "genre": { + "$in": [ + "comedy", + "documentary", + "drama" + ] + }, + "year": { + "$eq": 2019 + } + }, + "type": "object" + }, + "id": { + "description": "The unique ID of the vector to be used as a query vector. Each request can contain either the `vector` or `id` parameter.", + "example": "example-vector-1", + "maxLength": 512, + "type": "string" + }, + "includeMetadata": { + "default": "false", + "description": "Indicates whether metadata is included in the response as well as the ids.", + "example": true, + "type": "boolean" + }, + "includeValues": { + "default": "false", + "description": "Indicates whether vector values are included in the response. For on-demand indexes, setting this to `true` may increase latency, especially with higher `topK` values, because vector values are retrieved from object storage. Unless you need vector values, set this to `false` for better performance.", + "example": true, + "type": "boolean" + }, + "namespace": { + "description": "The namespace to query.", + "example": "example-namespace", + "type": "string" + }, + "queries": { + "deprecated": true, + "description": "DEPRECATED. Use `vector` or `id` instead.", + "items": { + "$ref": "#/components/schemas/QueryVector" + }, + "maxLength": 10, + "minLength": 1, + "type": "array" + }, + "sparseVector": { + "$ref": "#/components/schemas/SparseValues" + }, + "topK": { + "description": "The number of results to return for each query.", + "example": 10, + "format": "int64", + "maximum": 10000.0, + "minimum": 1.0, + "required": [ + "top_k" + ], + "type": "integer" + }, + "vector": { + "description": "The query vector. This should be the same length as the dimension of the index being queried. Each `query` request can contain only one of the parameters `id` or `vector`.", + "example": [ + 0.1, + 0.2, + 0.3, + 0.4, + 0.5, + 0.6, + 0.7, + 0.8 + ], + "items": { + "format": "float", + "type": "number" + }, + "maxLength": 20000, + "minLength": 1, + "type": "array" + } + }, + "required": [ + "topK" + ], + "type": "object" + }, + "QueryResponse": { + "description": "The response for the `query` operation. These are the matches found for a particular query vector. The matches are ordered from most similar to least similar.", + "properties": { + "matches": { + "description": "The matches for the vectors.", + "items": { + "$ref": "#/components/schemas/ScoredVector" + }, + "type": "array" + }, + "namespace": { + "description": "The namespace for the vectors.", + "type": "string" + }, + "results": { + "deprecated": true, + "description": "DEPRECATED. The results of each query. The order is the same as `QueryRequest.queries`.", + "items": { + "$ref": "#/components/schemas/SingleQueryResults" + }, + "type": "array" + }, + "usage": { + "$ref": "#/components/schemas/Usage" + } + }, + "type": "object" + }, + "QueryVector": { + "deprecated": true, + "description": "A single query vector within a `QueryRequest`.", + "properties": { + "filter": { + "description": "An override for the metadata filter to apply. This replaces the request-level filter.", + "example": { + "genre": { + "$in": [ + "comedy", + "documentary", + "drama" + ] + }, + "year": { + "$eq": 2019 + } + }, + "type": "object" + }, + "namespace": { + "description": "An override the namespace to search.", + "example": "example-namespace", + "type": "string" + }, + "sparseValues": { + "$ref": "#/components/schemas/SparseValues" + }, + "topK": { + "description": "An override for the number of results to return for this query vector.", + "example": 10, + "format": "int64", + "maximum": 10000, + "minimum": 1, + "type": "integer" + }, + "values": { + "description": "The query vector values. This should be the same length as the dimension of the index being queried.", + "example": [ + 0.1, + 0.2, + 0.3, + 0.4, + 0.5, + 0.6, + 0.7, + 0.8 + ], + "items": { + "format": "float", + "type": "number" + }, + "maxLength": 20000, + "minLength": 1, + "required": [ + "values" + ], + "type": "array" + } + }, + "required": [ + "values" + ], + "type": "object" + }, + "ScoredVector": { + "properties": { + "id": { + "description": "This is the vector's unique id.", + "example": "example-vector-1", + "maxLength": 512, + "minLength": 1, + "required": [ + "id" + ], + "type": "string" + }, + "metadata": { + "description": "This is the metadata, if it is requested.", + "example": { + "genre": "documentary", + "year": 2019 + }, + "type": "object" + }, + "score": { + "description": "This is a measure of similarity between this vector and the query vector. The higher the score, the more they are similar.", + "example": 0.08, + "format": "float", + "type": "number" + }, + "sparseValues": { + "$ref": "#/components/schemas/SparseValues" + }, + "values": { + "description": "This is the vector data, if it is requested.", + "example": [ + 0.1, + 0.2, + 0.3, + 0.4, + 0.5, + 0.6, + 0.7, + 0.8 + ], + "items": { + "format": "float", + "type": "number" + }, + "type": "array" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "SearchRecordsRequest": { + "description": "A search request for records in a specific namespace.", + "example": { + "fields": [ + "chunk_text" + ], + "query": { + "inputs": { + "text": "your query text" + }, + "top_k": 10 + } + }, + "properties": { + "fields": { + "description": "The fields to return in the search results. If not specified, the response will include all fields.", + "example": [ + "chunk_text" + ], + "items": { + "type": "string" + }, + "maxLength": 100, + "type": "array" + }, + "query": { + "description": ".", + "properties": { + "filter": { + "description": "The filter to apply. You can use vector metadata to limit your search. See [Understanding metadata](https://docs.pinecone.io/guides/index-data/indexing-overview#metadata).", + "type": "object" + }, + "id": { + "description": "The unique ID of the vector to be used as a query vector.", + "example": "example-vector-1", + "maxLength": 512, + "type": "string" + }, + "inputs": { + "$ref": "#/components/schemas/EmbedInputs" + }, + "top_k": { + "description": "The number of similar records to return.", + "example": 10, + "format": "int32", + "type": "integer" + }, + "vector": { + "$ref": "#/components/schemas/SearchRecordsVector" + } + }, + "required": [ + "top_k" + ], + "type": "object" + }, + "rerank": { + "description": "Parameters for reranking the initial search results.", + "properties": { + "model": { + "description": "The name of the [reranking model](https://docs.pinecone.io/guides/search/rerank-results#reranking-models) to use.", + "example": "bge-reranker-v2-m3", + "type": "string" + }, + "parameters": { + "additionalProperties": true, + "description": "Additional model-specific parameters. Refer to the [model guide](https://docs.pinecone.io/guides/search/rerank-results#reranking-models) for available model parameters.", + "example": { + "truncate": "END" + }, + "type": "object" + }, + "query": { + "description": "The query to rerank documents against. If a specific rerank query is specified, it overwrites the query input that was provided at the top level.", + "example": "What is the capital of France?", + "type": "string" + }, + "rank_fields": { + "description": "The field(s) to consider for reranking. If not provided, the default is `[\"text\"]`.\n\nThe number of fields supported is [model-specific](https://docs.pinecone.io/guides/search/rerank-results#reranking-models).\n", + "example": [ + "chunk_text", + "title" + ], + "items": { + "type": "string" + }, + "type": "array" + }, + "top_n": { + "description": "The number of top results to return after reranking. Defaults to top_k.", + "example": 5, + "format": "int32", + "type": "integer" + } + }, + "required": [ + "model", + "rank_fields" + ], + "type": "object" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "SearchRecordsResponse": { + "description": "The records search response.", + "example": { + "result": { + "hits": [ + { + "_id": "example-record-1", + "_score": 0.9281134605407715, + "fields": { + "data": "your example text" + } + } + ] + }, + "usage": { + "embed_total_tokens": 10, + "read_units": 5 + } + }, + "properties": { + "result": { + "properties": { + "hits": { + "description": "The hits for the search document request.", + "items": { + "$ref": "#/components/schemas/Hit" + }, + "type": "array" + } + }, + "required": [ + "hits" + ], + "type": "object" + }, + "usage": { + "$ref": "#/components/schemas/SearchUsage" + } + }, + "required": [ + "usage", + "result" + ], + "type": "object" + }, + "SearchRecordsVector": { + "properties": { + "sparse_indices": { + "description": "The sparse embedding indices.", + "example": [ + 10, + 3, + 156 + ], + "items": { + "format": "int32", + "minimum": 0, + "type": "integer" + }, + "type": "array" + }, + "sparse_values": { + "description": "The sparse embedding values.", + "example": [ + 0.1, + 0.2, + 0.3 + ], + "items": { + "format": "float", + "type": "number" + }, + "type": "array" + }, + "values": { + "$ref": "#/components/schemas/VectorValues" + } + }, + "type": "object" + }, + "SearchUsage": { + "properties": { + "embed_total_tokens": { + "description": "The number of embedding tokens consumed by this operation.", + "example": 2, + "format": "int32", + "minimum": 0, + "type": "integer" + }, + "read_units": { + "description": "The number of read units consumed by this operation.", + "example": 5, + "format": "int32", + "minimum": 0, + "type": "integer" + }, + "rerank_units": { + "description": "The number of rerank units consumed by this operation.", + "example": 1, + "format": "int32", + "minimum": 0, + "type": "integer" + } + }, + "required": [ + "read_units" + ], + "type": "object" + }, + "SearchVector": { + "properties": { + "values": { + "$ref": "#/components/schemas/VectorValues" + } + }, + "type": "object" + }, + "SingleQueryResults": { + "properties": { + "matches": { + "description": "The matches for the vectors.", + "items": { + "$ref": "#/components/schemas/ScoredVector" + }, + "type": "array" + }, + "namespace": { + "description": "The namespace for the vectors.", + "example": "example-namespace", + "type": "string" + } + }, + "title": "The query results for a single `QueryVector`", + "type": "object" + }, + "SparseValues": { + "description": "Vector sparse data. Represented as a list of indices and a list of corresponded values, which must be with the same length.", + "properties": { + "indices": { + "description": "The indices of the sparse data.", + "example": [ + 1, + 312, + 822, + 14, + 980 + ], + "items": { + "format": "int64", + "type": "integer" + }, + "maxLength": 1000, + "minLength": 1, + "required": [ + "indices" + ], + "type": "array" + }, + "values": { + "description": "The corresponding values of the sparse data, which must be with the same length as the indices.", + "example": [ + 0.1, + 0.2, + 0.3, + 0.4, + 0.5 + ], + "items": { + "format": "float", + "type": "number" + }, + "maxLength": 1000, + "minLength": 1, + "required": [ + "values" + ], + "type": "array" + } + }, + "required": [ + "indices", + "values" + ], + "type": "object" + }, + "StartImportRequest": { + "description": "The request for the `start_import` operation.", + "properties": { + "errorMode": { + "$ref": "#/components/schemas/ImportErrorMode" + }, + "integrationId": { + "description": "The id of the [storage integration](https://docs.pinecone.io/guides/operations/integrations/manage-storage-integrations) that should be used to access the data.", + "maxLength": 1000, + "type": "string" + }, + "uri": { + "description": "The URI of the bucket (or container) and import directory containing the namespaces and Parquet files you want to import. For example, `s3://BUCKET_NAME/IMPORT_DIR` for Amazon S3, `gs://BUCKET_NAME/IMPORT_DIR` for Google Cloud Storage, or `https://STORAGE_ACCOUNT.blob.core.windows.net/CONTAINER_NAME/IMPORT_DIR` for Azure Blob Storage. For more information, see [Import records](https://docs.pinecone.io/guides/index-data/import-data#prepare-your-data).", + "maxLength": 1500, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "uri" + ], + "type": "object" + }, + "StartImportResponse": { + "description": "The response for the `start_import` operation.", + "properties": { + "id": { + "description": "Unique identifier for the import operation.", + "example": "101", + "maxLength": 1000, + "minLength": 1, + "type": "string" + } + }, + "type": "object" + }, + "UpdateRequest": { + "description": "The request for the `update` operation.", + "properties": { + "id": { + "description": "Vector's unique id.", + "example": "example-vector-1", + "maxLength": 512, + "minLength": 1, + "required": [ + "id" + ], + "type": "string" + }, + "namespace": { + "description": "The namespace containing the vector to update.", + "example": "example-namespace", + "type": "string" + }, + "setMetadata": { + "description": "Metadata to set for the vector.", + "example": { + "genre": "documentary", + "year": 2019 + }, + "type": "object" + }, + "sparseValues": { + "$ref": "#/components/schemas/SparseValues" + }, + "values": { + "description": "Vector data.", + "example": [ + 0.1, + 0.2, + 0.3, + 0.4, + 0.5, + 0.6, + 0.7, + 0.8 + ], + "items": { + "format": "float", + "type": "number" + }, + "maxLength": 20000, + "minLength": 1, + "type": "array" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "UpdateResponse": { + "description": "The response for the `update` operation.", + "type": "object" + }, + "UpsertRecord": { + "description": "The request for the `upsert` operation.", + "example": { + "_id": "example-record-1" + }, + "properties": { + "_id": { + "description": "The unique ID of the record to upsert. Note that `id` can be used as an alias for `_id`.", + "type": "string" + } + }, + "required": [ + "_id" + ], + "type": "object" + }, + "UpsertRequest": { + "description": "The request for the `upsert` operation.", + "properties": { + "namespace": { + "description": "The namespace where you upsert vectors.", + "example": "example-namespace", + "type": "string" + }, + "vectors": { + "description": "An array containing the vectors to upsert. Recommended batch limit is up to 1000 vectors.", + "items": { + "$ref": "#/components/schemas/Vector" + }, + "maxLength": 1000, + "minLength": 1, + "type": "array" + } + }, + "required": [ + "vectors" + ], + "type": "object" + }, + "UpsertResponse": { + "description": "The response for the `upsert` operation.", + "properties": { + "upsertedCount": { + "description": "The number of vectors upserted.", + "example": 2, + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, + "Usage": { + "properties": { + "readUnits": { + "description": "The number of read units consumed by this operation.", + "example": 5, + "format": "int64", + "type": "integer" + } + }, + "type": "object" + }, + "Vector": { + "properties": { + "id": { + "description": "This is the vector's unique id.", + "example": "example-vector-1", + "maxLength": 512, + "minLength": 1, + "required": [ + "id" + ], + "type": "string" + }, + "metadata": { + "description": "This is the metadata included in the request.", + "example": { + "genre": "documentary", + "year": 2019 + }, + "type": "object" + }, + "sparseValues": { + "$ref": "#/components/schemas/SparseValues" + }, + "values": { + "description": "This is the vector data included in the request.", + "example": [ + 0.1, + 0.2, + 0.3, + 0.4, + 0.5, + 0.6, + 0.7, + 0.8 + ], + "items": { + "format": "float", + "type": "number" + }, + "maxLength": 20000, + "minLength": 1, + "required": [ + "values" + ], + "type": "array" + } + }, + "required": [ + "id" + ], + "type": "object" + }, + "VectorValues": { + "description": "This is the vector data included in the request.", + "items": { + "format": "float", + "type": "number" + }, + "maxLength": 20000, + "minLength": 1, + "type": "array" + }, + "protobufAny": { + "properties": { + "typeUrl": { + "type": "string" + }, + "value": { + "format": "byte", + "type": "string" + } + }, + "type": "object" + }, + "protobufNullValue": { + "default": "NULL_VALUE", + "description": "`NullValue` is a singleton enumeration to represent the null value for the `Value` type union.\nThe JSON representation for `NullValue` is JSON `null`.", + "enum": [ + "NULL_VALUE" + ], + "type": "string" + }, + "rpcStatus": { + "properties": { + "code": { + "format": "int32", + "type": "integer" + }, + "details": { + "items": { + "$ref": "#/components/schemas/protobufAny" + }, + "type": "array" + }, + "message": { + "type": "string" + } + }, + "type": "object" + } + }, + "securitySchemes": { + "ApiKeyAuth": { + "description": "An API Key is required to call Pinecone APIs. Get yours from the [console](https://app.pinecone.io/).", + "in": "header", + "name": "Api-Key", + "type": "apiKey" + } + } + }, + "externalDocs": { + "description": "More Pinecone.io API docs", + "url": "https://docs.pinecone.io/introduction" + }, + "info": { + "contact": { + "email": "support@pinecone.io", + "name": "Pinecone Support", + "url": "https://support.pinecone.io" + }, + "description": "Pinecone is a vector database that makes it easy to search and retrieve billions of high-dimensional vectors.", + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0" + }, + "title": "Pinecone Data Plane API", + "version": "2025-04" + }, + "openapi": "3.0.3", + "paths": { + "/bulk/imports": { + "get": { + "description": "List all recent and ongoing import operations.\n\nBy default, `list_imports` returns up to 100 imports per page. If the `limit` parameter is set, `list` returns up to that number of imports instead. Whenever there are additional IDs to return, the response also includes a `pagination_token` that you can use to get the next batch of imports. When the response does not include a `pagination_token`, there are no more imports to return.\n\nFor guidance and examples, see [Import data](https://docs.pinecone.io/guides/index-data/import-data).", + "operationId": "listBulkImports", + "parameters": [ + { + "description": "Max number of operations to return per page.", + "example": 10, + "in": "query", + "name": "limit", + "schema": { + "default": "100", + "format": "int32", + "maximum": 100, + "minimum": 1, + "type": "integer" + }, + "style": "form" + }, + { + "description": "Pagination token to continue a previous listing operation.", + "in": "query", + "name": "paginationToken", + "schema": { + "type": "string" + }, + "style": "form" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListImportsResponse" + } + } + }, + "description": "A list of import operations" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "List imports", + "tags": [ + "Bulk Operations" + ] + }, + "post": { + "description": "Start an asynchronous import of vectors from object storage into an index.\n\nFor guidance and examples, see [Import data](https://docs.pinecone.io/guides/index-data/import-data).", + "operationId": "startBulkImport", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StartImportRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StartImportResponse" + } + } + }, + "description": "Successful import operation" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Start import", + "tags": [ + "Bulk Operations" + ] + } + }, + "/bulk/imports/{id}": { + "delete": { + "description": "Cancel an import operation if it is not yet finished. It has no effect if the operation is already finished.\n\nFor guidance and examples, see [Import data](https://docs.pinecone.io/guides/index-data/import-data).", + "operationId": "cancelBulkImport", + "parameters": [ + { + "description": "Unique identifier for the import operation.", + "example": "101", + "in": "path", + "name": "id", + "required": true, + "schema": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CancelImportResponse" + } + } + }, + "description": "Operation cancelled successfully" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Cancel an import", + "tags": [ + "Bulk Operations" + ] + }, + "get": { + "description": "Return details of a specific import operation.\n\nFor guidance and examples, see [Import data](https://docs.pinecone.io/guides/index-data/import-data).", + "operationId": "describeBulkImport", + "parameters": [ + { + "description": "Unique identifier for the import operation.", + "example": "101", + "in": "path", + "name": "id", + "required": true, + "schema": { + "maxLength": 1000, + "minLength": 1, + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportModel" + } + } + }, + "description": "Details of the import operation." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Describe an import", + "tags": [ + "Bulk Operations" + ] + } + }, + "/describe_index_stats": { + "post": { + "description": "Return statistics about the contents of an index, including the vector count per namespace, the number of dimensions, and the index fullness.\n\nServerless indexes scale automatically as needed, so index fullness is relevant only for pod-based indexes.", + "operationId": "describeIndexStats", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DescribeIndexStatsRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IndexDescription" + } + } + }, + "description": "A successful response." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Get index stats", + "tags": [ + "Vector Operations" + ] + } + }, + "/namespaces": { + "get": { + "description": "List all namespaces in a serverless index.\n\nUp to 100 namespaces are returned at a time by default, in sorted order (bitwise \u201cC\u201d collation). If the `limit` parameter is set, up to that number of namespaces are returned instead. Whenever there are additional namespaces to return, the response also includes a `pagination_token` that you can use to get the next batch of namespaces. When the response does not include a `pagination_token`, there are no more namespaces to return.\n\nFor guidance and examples, see [Manage namespaces](https://docs.pinecone.io/guides/manage-data/manage-namespaces).\n\n**Note:** This operation is not supported for pod-based indexes.", + "operationId": "listNamespacesOperation", + "parameters": [ + { + "description": "Max number namespaces to return per page.", + "example": 10, + "in": "query", + "name": "limit", + "schema": { + "format": "int32", + "type": "integer" + }, + "style": "form" + }, + { + "description": "Pagination token to continue a previous listing operation.", + "in": "query", + "name": "paginationToken", + "schema": { + "type": "string" + }, + "style": "form" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListNamespacesResponse" + } + } + }, + "description": "A successful response" + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "List namespaces", + "tags": [ + "Namespace Operations" + ] + } + }, + "/namespaces/{namespace}": { + "delete": { + "description": "Delete a namespace from a serverless index. Deleting a namespace is irreversible; all data in the namespace is permanently deleted.\n\nFor guidance and examples, see [Manage namespaces](https://docs.pinecone.io/guides/manage-data/manage-namespaces).\n\n**Note:** This operation is not supported for pod-based indexes.", + "operationId": "deleteNamespace", + "parameters": [ + { + "description": "The namespace to delete", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteResponse" + } + } + }, + "description": "A successful response" + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Delete a namespace", + "tags": [ + "Namespace Operations" + ] + }, + "get": { + "description": "Describe a namespace in a serverless index, including the total number of vectors in the namespace.\n\nFor guidance and examples, see [Manage namespaces](https://docs.pinecone.io/guides/manage-data/manage-namespaces).\n\n**Note:** This operation is not supported for pod-based indexes.", + "operationId": "describeNamespace", + "parameters": [ + { + "description": "The namespace to describe", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NamespaceDescription" + } + } + }, + "description": "A description of a namespace." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Describe a namespace", + "tags": [ + "Namespace Operations" + ] + } + }, + "/query": { + "post": { + "description": "Search a namespace using a query vector. It retrieves the ids of the most similar items in a namespace, along with their similarity scores.\n\nFor guidance, examples, and limits, see [Search](https://docs.pinecone.io/guides/search/search-overview).", + "operationId": "queryVectors", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueryRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueryResponse" + } + } + }, + "description": "A successful response." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Search with a vector", + "tags": [ + "Vector Operations" + ] + } + }, + "/records/namespaces/{namespace}/search": { + "post": { + "description": "Search a namespace with a query text, query vector, or record ID and return the most similar records, along with their similarity scores. Optionally, rerank the initial results based on their relevance to the query. \n\nSearching with text is supported only for [indexes with integrated embedding](https://docs.pinecone.io/guides/indexes/create-an-index#integrated-embedding). Searching with a query vector or record ID is supported for all indexes. \n\nFor guidance, examples, and limits, see [Search](https://docs.pinecone.io/guides/search/search-overview).", + "operationId": "searchRecordsNamespace", + "parameters": [ + { + "description": "The namespace to search.", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchRecordsRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchRecordsResponse" + } + } + }, + "description": "A successful search namespace response." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Search with text", + "tags": [ + "Vector Operations" + ] + } + }, + "/records/namespaces/{namespace}/upsert": { + "post": { + "description": "Upsert text into a namespace. Pinecone converts the text to vectors automatically using the hosted embedding model associated with the index.\n\nUpserting text is supported only for [indexes with integrated embedding](https://docs.pinecone.io/guides/index-data/create-an-index#embedding-models).\n\nFor guidance, examples, and limits, see [Upsert data](https://docs.pinecone.io/guides/index-data/upsert-data).", + "operationId": "upsertRecordsNamespace", + "parameters": [ + { + "description": "The namespace to upsert records into.", + "in": "path", + "name": "namespace", + "required": true, + "schema": { + "type": "string" + }, + "style": "simple" + } + ], + "requestBody": { + "content": { + "application/x-ndjson": { + "schema": { + "items": { + "$ref": "#/components/schemas/UpsertRecord" + }, + "type": "array" + } + } + }, + "description": "Each record in the request body must include an `_id` field and a field that matches your index's `field_map` configuration (such as `chunk_text` or `data`). All other fields are stored as metadata.\n", + "required": true + }, + "responses": { + "201": { + "description": "A successful response." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Upsert text", + "tags": [ + "Vector Operations" + ] + } + }, + "/vectors/delete": { + "post": { + "description": "Delete vectors by id from a single namespace.\n\nFor guidance and examples, see [Delete data](https://docs.pinecone.io/guides/manage-data/delete-data).", + "operationId": "deleteVectors", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteResponse" + } + } + }, + "description": "A successful response." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Delete vectors", + "tags": [ + "Vector Operations" + ] + } + }, + "/vectors/fetch": { + "get": { + "description": "Look up and return vectors by ID from a single namespace. The returned vectors include the vector data and/or metadata.\n\nFor on-demand indexes, since vector values are retrieved from object storage, fetch operations may have increased latency. If you only need metadata or IDs, consider using the query operation with `includeValues` set to `false` instead.\n\nFor guidance and examples, see [Fetch data](https://docs.pinecone.io/guides/manage-data/fetch-data).", + "operationId": "fetchVectors", + "parameters": [ + { + "description": "The vector IDs to fetch. Does not accept values containing spaces.", + "explode": true, + "in": "query", + "name": "ids", + "required": true, + "schema": { + "items": { + "type": "string" + }, + "type": "array" + }, + "style": "form" + }, + { + "in": "query", + "name": "namespace", + "schema": { + "type": "string" + }, + "style": "form" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FetchResponse" + } + } + }, + "description": "A successful response." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Fetch vectors", + "tags": [ + "Vector Operations" + ] + } + }, + "/vectors/list": { + "get": { + "description": "List the IDs of vectors in a single namespace of a serverless index. An optional prefix can be passed to limit the results to IDs with a common prefix.\n\nReturns up to 100 IDs at a time by default in sorted order (bitwise \"C\" collation). If the `limit` parameter is set, `list` returns up to that number of IDs instead. Whenever there are additional IDs to return, the response also includes a `pagination_token` that you can use to get the next batch of IDs. When the response does not include a `pagination_token`, there are no more IDs to return.\n\nFor guidance and examples, see [List record IDs](https://docs.pinecone.io/guides/manage-data/list-record-ids).\n\n**Note:** `list` is supported only for serverless indexes.", + "operationId": "listVectors", + "parameters": [ + { + "description": "The vector IDs to fetch. Does not accept values containing spaces.", + "in": "query", + "name": "prefix", + "schema": { + "type": "string" + }, + "style": "form" + }, + { + "description": "Max number of IDs to return per page.", + "in": "query", + "name": "limit", + "schema": { + "default": "100", + "format": "int64", + "type": "integer" + }, + "style": "form" + }, + { + "description": "Pagination token to continue a previous listing operation.", + "in": "query", + "name": "paginationToken", + "schema": { + "type": "string" + }, + "style": "form" + }, + { + "in": "query", + "name": "namespace", + "schema": { + "type": "string" + }, + "style": "form" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ListResponse" + } + } + }, + "description": "A successful response." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "List vector IDs", + "tags": [ + "Vector Operations" + ] + } + }, + "/vectors/update": { + "post": { + "description": "Update a vector in a namespace. If a value is included, it will overwrite the previous value. If a `set_metadata` is included, the values of the fields specified in it will be added or overwrite the previous value.\n\nFor guidance and examples, see [Update data](https://docs.pinecone.io/guides/manage-data/update-data).", + "operationId": "updateVector", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateResponse" + } + } + }, + "description": "A successful response." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Update a vector", + "tags": [ + "Vector Operations" + ] + } + }, + "/vectors/upsert": { + "post": { + "description": "Upsert vectors into a namespace. If a new value is upserted for an existing vector ID, it will overwrite the previous value.\n\nFor guidance, examples, and limits, see [Upsert data](https://docs.pinecone.io/guides/index-data/upsert-data).", + "operationId": "upsertVectors", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertResponse" + } + } + }, + "description": "A successful response." + }, + "400": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "Bad request. The request body included invalid request parameters." + }, + "4XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + }, + "5XX": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/rpcStatus" + } + } + }, + "description": "An unexpected error response." + } + }, + "summary": "Upsert vectors", + "tags": [ + "Vector Operations" + ] + } + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "servers": [ + { + "url": "https://{index_host}", + "variables": { + "index_host": { + "default": "unknown", + "description": "host of the index" + } + } + } + ], + "tags": [ + { + "name": "Vector Operations" + }, + { + "name": "Bulk Operations" + }, + { + "name": "Namespace Operations" + } + ] +} diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..086fbda --- /dev/null +++ b/requirements.txt @@ -0,0 +1,7 @@ +# a2a-pack is installed by the platform base image. +deepagents>=0.5.0 +langchain>=0.3 +langchain-openai>=0.2 +langchain-core>=0.3 +langgraph>=0.6 +httpx>=0.27