everyrow 0.1.0__tar.gz → 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- everyrow-0.1.1/.claude-plugin/marketplace.json +17 -0
- everyrow-0.1.1/PKG-INFO +275 -0
- everyrow-0.1.1/README.md +263 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/case_studies/dedupe/case_01_crm_data.ipynb +3 -29
- everyrow-0.1.1/case_studies/screen/oil_price_margin_screen.ipynb +517 -0
- everyrow-0.1.1/case_studies/screen/oil_price_margin_screen_results.csv +151 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/case_studies/screen/thematic_stock_screen.ipynb +4 -34
- everyrow-0.1.1/docs/DEDUPE.md +90 -0
- everyrow-0.1.1/docs/MERGE.md +79 -0
- everyrow-0.1.1/docs/RANK.md +86 -0
- everyrow-0.1.1/docs/SCREEN.md +104 -0
- everyrow-0.1.0/examples/clean_example.py → everyrow-0.1.1/examples/dedupe_example.py +2 -14
- everyrow-0.1.1/examples/derive_example.py +41 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/examples/merge_example.py +2 -14
- everyrow-0.1.1/examples/rank_example.py +82 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/examples/screen_example.py +6 -34
- everyrow-0.1.1/examples/simple_call.py +32 -0
- everyrow-0.1.1/images/future-search-logo-128.webp +0 -0
- everyrow-0.1.1/plugins/everyrow/.claude-plugin/plugin.json +9 -0
- everyrow-0.1.1/plugins/everyrow/skills/everyrow-sdk/SKILL.md +206 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/pyproject.toml +1 -1
- everyrow-0.1.1/src/everyrow/__init__.py +5 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/citations.py +6 -2
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/ops.py +154 -54
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/session.py +33 -11
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/task.py +99 -15
- {everyrow-0.1.0 → everyrow-0.1.1}/uv.lock +1 -1
- everyrow-0.1.0/PKG-INFO +0 -238
- everyrow-0.1.0/README.md +0 -226
- everyrow-0.1.0/examples/derive_example.py +0 -49
- everyrow-0.1.0/examples/rank_example.py +0 -144
- everyrow-0.1.0/examples/simple_call.py +0 -87
- everyrow-0.1.0/src/everyrow/__init__.py +0 -4
- everyrow-0.1.0/thematic_screen_results_20260114_172950.csv +0 -10
- {everyrow-0.1.0 → everyrow-0.1.1}/.env.example +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/.github/workflows/ci.yaml +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/.github/workflows/publish.yaml +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/.gitignore +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/LICENSE.txt +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/case_studies/dedupe/case_01_crm_data.csv +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/case_studies/screen/S&P 500 Companies.csv +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/case_studies/screen/thematic_screen_results.csv +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/generate_openapi.sh +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/lefthook.yml +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/openapi-python-client.yaml +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/api_utils.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/constants.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/__init__.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/__init__.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/__init__.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/continue_task_endpoint_tasks_continue_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/copy_artifacts_artifacts_copy_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/copy_workflow_endpoint_workflows_copy_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/create_api_key_endpoint_api_keys_create_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/create_session_endpoint_sessions_create_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/create_workflow_from_artifact_workflows_from_artifact_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/export_to_google_sheets_export_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/generate_feedback_endpoint_tasks_generate_feedback_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/get_artifacts_artifacts_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/get_default_timeout_seconds_models_default_timeout_seconds_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/get_job_progress_for_task_jobs_progress_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/get_metrics_metrics_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/get_queues_stats_jobs_queues_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/get_task_status_endpoint_tasks_task_id_status_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/get_user_usage_usage_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/healthz_healthz_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/import_from_google_sheets_import_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/interrupt_chat_task_tasks_chat_interrupt_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/list_api_keys_endpoint_api_keys_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/re_execute_task_endpoint_tasks_re_execute_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/revoke_api_key_endpoint_api_keys_key_id_revoke_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/revoke_jobs_for_task_jobs_revoke_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/rollback_to_message_endpoint_tasks_chat_rollback_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/submit_chat_task_tasks_chat_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/submit_task_tasks_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/task_resource_estimation_task_resource_estimation_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/trigger_workflow_execution_endpoint_workflows_trigger_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/api/default/whoami_whoami_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/client.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/errors.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/__init__.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/agent_improvement_instruction.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/agent_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/agent_query_params_system_prompt_kind_type_0.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/agent_task_args.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/agent_task_args_processing_mode.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/allowed_suggestions.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/api_key_info.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/artifact_changed_payload.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/artifact_group_record.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/artifact_group_record_metadata_type_0.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/artifact_group_record_trace_mapping_type_0.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/artifact_status.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/auto_cohort_conversation_message.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/aux_data.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/aux_data_source_bank.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/chat_completion_message_tool_call.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/chat_message_metadata.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/concatenate_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/concatenate_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/continue_reason.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/continue_task_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/controller_improvement_round.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/conversation_changed_payload.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/copy_artifacts_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/copy_artifacts_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/copy_workflow_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/copy_workflow_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/create_api_key_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/create_api_key_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/create_group_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/create_group_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/create_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/create_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/create_session_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/create_session_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/create_workflow_from_artifact_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/create_workflow_from_artifact_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/data_frame_method.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/date_cutoffs.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/dedupe_mode.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/dedupe_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/dedupe_request_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/deep_merge_public_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/deep_merge_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/deep_rank_public_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/deep_rank_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/deep_screen_public_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/deep_screen_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/derive_expression.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/derive_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/derive_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/document_query_tool.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/drop_columns_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/drop_columns_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/embedding_models.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/event_type.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/execution_metadata.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/export_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/export_request_token_data.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/export_to_google_sheets_export_post_response_export_to_google_sheets_export_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/filter_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/filter_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/flatten_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/flatten_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/generate_feedback_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/group_by_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/group_by_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/healthz_healthz_get_response_healthz_healthz_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/http_validation_error.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/image_chat_content_part.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/image_chat_content_part_image_url.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/import_from_google_sheets_import_post_response_import_from_google_sheets_import_post.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/import_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/import_request_token_data.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/insufficient_balance_error.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/join_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/join_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/llm_enum.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/map_agent_request_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/map_multi_agent_request_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/message_created_payload.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/multi_agent_effort_level.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/multi_agent_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/multi_modal_chat_message.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/multi_modal_chat_message_role.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/preview_metadata.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/processing_mode.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/progress_status.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/queue_stats.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/reduce_agent_request_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/reduce_multi_agent_request_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/resource_estimation_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/response_schema_type.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/revoke_api_key_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/rollback_to_message_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/rollback_to_message_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/session_changed_payload.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/simple_chat_message.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/simple_chat_message_role.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/simple_chat_message_with_tool_calls.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/source_database_entry.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/standalone_artifact_record.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/standalone_artifact_record_metadata_type_0.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/standalone_artifact_record_trace_mapping_type_0.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/status_count.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/status_count_status.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/submit_chat_task_body.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/submit_chat_task_body_selected_task_type_type_0.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/submit_task_body.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_changed_payload.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_effort.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_id_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_insert.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_insert_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_metadata.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_metadata_cols_to_rename_type_0.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_status.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_status_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/task_type.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/text_chat_content_part.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/tool_response_message.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/toolkit_constants.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/trace_changed_payload.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/trace_info.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/trigger_workflow_execution_request.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/trigger_workflow_execution_request_task_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/trigger_workflow_execution_request_task_params_additional_property.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/trigger_workflow_execution_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/upload_csv_payload.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/upload_csv_query_params.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/usage_response.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/validation_error.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/whoami_whoami_get_response_whoami_whoami_get.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/models/workflow_leaf_node_input.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/py.typed +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/generated/types.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/src/everyrow/result.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/tests/__init__.py +0 -0
- {everyrow-0.1.0 → everyrow-0.1.1}/tests/test_ops.py +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "futuresearch",
|
|
3
|
+
"owner": {
|
|
4
|
+
"name": "FutureSearch"
|
|
5
|
+
},
|
|
6
|
+
"metadata": {
|
|
7
|
+
"description": "AI-powered data processing plugins from FutureSearch"
|
|
8
|
+
},
|
|
9
|
+
"plugins": [
|
|
10
|
+
{
|
|
11
|
+
"name": "everyrow",
|
|
12
|
+
"source": "./plugins/everyrow",
|
|
13
|
+
"description": "Claude Code plugin for the everyrow SDK - AI-powered data processing utilities for transforming, deduping, merging, ranking, and screening dataframes",
|
|
14
|
+
"version": "1.0.0"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
everyrow-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: everyrow
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: An SDK for everyrow.io: agent ops at spreadsheet scale
|
|
5
|
+
License-File: LICENSE.txt
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Requires-Dist: attrs>=25.4.0
|
|
8
|
+
Requires-Dist: pandas>=2.3.3
|
|
9
|
+
Requires-Dist: pydantic>=2.12.5
|
|
10
|
+
Requires-Dist: python-dotenv>=1.2.1
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
# <picture><img src="images/future-search-logo-128.webp" alt="FutureSearch" height="24" align="bottom"></picture> everyrow SDK
|
|
16
|
+
|
|
17
|
+
Python SDK for [everyrow.io](https://everyrow.io). Rank, dedupe, merge, and screen your dataframes using natural language—or run web agents to research every row.
|
|
18
|
+
|
|
19
|
+
## Table of Contents
|
|
20
|
+
|
|
21
|
+
New to everyrow? Head to [Getting Started](#getting-started)
|
|
22
|
+
|
|
23
|
+
Looking to use our agent-backed utilities? Check out:
|
|
24
|
+
- [Rank](#rank)
|
|
25
|
+
- [Dedupe](#dedupe)
|
|
26
|
+
- [Merge](#merge)
|
|
27
|
+
- [Screen](#screen)
|
|
28
|
+
- [Agent Tasks](#agent-tasks)
|
|
29
|
+
|
|
30
|
+
## Getting Started
|
|
31
|
+
|
|
32
|
+
Get an API key at [everyrow.io](https://everyrow.io).
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
export EVERYROW_API_KEY=your_api_key_here
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install everyrow
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
For development:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
uv pip install -e .
|
|
48
|
+
uv sync
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Requires Python >= 3.12
|
|
52
|
+
|
|
53
|
+
### Claude Code Plugin
|
|
54
|
+
|
|
55
|
+
There's a plugin for [Claude Code](https://code.claude.com/) that teaches Claude how to use the SDK:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
# from Claude Code
|
|
59
|
+
/plugin marketplace add futuresearch/everyrow-sdk
|
|
60
|
+
/plugin install everyrow@futuresearch
|
|
61
|
+
|
|
62
|
+
# from terminal
|
|
63
|
+
claude plugin marketplace add futuresearch/everyrow-sdk
|
|
64
|
+
claude plugin install everyrow@futuresearch
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Rank
|
|
68
|
+
|
|
69
|
+
Score rows based on criteria you can't put in a database field. The AI researches each row and assigns scores based on qualitative factors.
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from everyrow.ops import rank
|
|
73
|
+
|
|
74
|
+
result = await rank(
|
|
75
|
+
task="Score by likelihood to need data integration solutions",
|
|
76
|
+
input=leads_dataframe,
|
|
77
|
+
field_name="integration_need_score",
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Say you want to rank leads by "likelihood to need data integration tools"—Ultramain Systems (sells software to airlines) looks similar to Ukraine International Airlines (is an airline) by industry code, but their actual needs are completely different. Traditional scoring can't tell them apart.
|
|
82
|
+
|
|
83
|
+
**Case studies:** [Lead Scoring with Data Fragmentation](https://futuresearch.ai/lead-scoring-data-fragmentation/) (1,000 leads, 7 min, $13) · [Lead Scoring Without CRM](https://futuresearch.ai/lead-scoring-without-crm/) ($28 vs $145 with Clay)
|
|
84
|
+
|
|
85
|
+
[Full documentation →](docs/RANK.md)
|
|
86
|
+
|
|
87
|
+
### Dedupe
|
|
88
|
+
|
|
89
|
+
Deduplicate when fuzzy matching falls short. The AI understands that "AbbVie Inc", "Abbvie", and "AbbVie Pharmaceutical" are the same company, or that "Big Blue" means IBM.
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from everyrow.ops import dedupe
|
|
93
|
+
|
|
94
|
+
result = await dedupe(
|
|
95
|
+
input=crm_data,
|
|
96
|
+
equivalence_relation="Two entries are duplicates if they represent the same legal entity",
|
|
97
|
+
)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The `equivalence_relation` tells the AI what counts as a duplicate—natural language, not regex. Results include `equivalence_class_id` (groups duplicates), `equivalence_class_name` (human-readable cluster name), and `selected` (the canonical record in each cluster).
|
|
101
|
+
|
|
102
|
+
**Case studies:** [CRM Deduplication](https://futuresearch.ai/crm-deduplication/) (500→124 rows, 2 min, $1.67) · [Researcher Deduplication](https://futuresearch.ai/researcher-dedupe-case-study/) (98% accuracy with career changes)
|
|
103
|
+
|
|
104
|
+
[Full documentation →](docs/DEDUPE.md)
|
|
105
|
+
|
|
106
|
+
### Merge
|
|
107
|
+
|
|
108
|
+
Join two tables when the keys don't match exactly—or at all. The AI knows "Photoshop" belongs to "Adobe" and "Genentech" is a Roche subsidiary, even with zero string similarity.
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from everyrow.ops import merge
|
|
112
|
+
|
|
113
|
+
result = await merge(
|
|
114
|
+
task="Match each software product to its parent company",
|
|
115
|
+
left_table=software_products,
|
|
116
|
+
right_table=approved_suppliers,
|
|
117
|
+
merge_on_left="software_name",
|
|
118
|
+
merge_on_right="company_name",
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Handles subsidiaries, abbreviations (MSD → Merck), regional names, typos, and pseudonyms. Fuzzy matching thresholds always fail somewhere—0.9 misses "Colfi" ↔ "Dr. Ioana Colfescu", 0.7 false-positives on "John Smith" ↔ "Jane Smith".
|
|
123
|
+
|
|
124
|
+
**Case studies:** [Software Supplier Matching](https://futuresearch.ai/software-supplier-matching/) (2,000 products, 91% accuracy, $9) · [HubSpot Contact Merge](https://futuresearch.ai/merge-hubspot-contacts/) (99.9% recall) · [CRM Merge Workflow](https://futuresearch.ai/crm-merge-workflow/)
|
|
125
|
+
|
|
126
|
+
[Full documentation →](docs/MERGE.md)
|
|
127
|
+
|
|
128
|
+
### Screen
|
|
129
|
+
|
|
130
|
+
Filter rows based on criteria that require research—things you can't express in SQL. The AI actually researches each row (10-Ks, earnings reports, news) before deciding pass/fail.
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from everyrow.ops import screen
|
|
134
|
+
from pydantic import BaseModel, Field
|
|
135
|
+
|
|
136
|
+
class ScreenResult(BaseModel):
|
|
137
|
+
passes: bool = Field(description="True if company meets the criteria")
|
|
138
|
+
|
|
139
|
+
result = await screen(
|
|
140
|
+
task="""
|
|
141
|
+
Find companies with >75% recurring revenue that would benefit from
|
|
142
|
+
Taiwan tensions - CHIPS Act beneficiaries, defense contractors,
|
|
143
|
+
cybersecurity firms. Exclude companies dependent on Taiwan manufacturing.
|
|
144
|
+
""",
|
|
145
|
+
input=sp500_companies,
|
|
146
|
+
response_model=ScreenResult,
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Works for investment theses, geopolitical exposure, vendor risk assessment, job posting filtering, lead qualification—anything requiring judgment. Screening 500 S&P 500 companies takes ~12 min and $3 with >90% precision. Regex gets 68%.
|
|
151
|
+
|
|
152
|
+
**Case studies:** [Thematic Stock Screen](https://futuresearch.ai/thematic-stock-screening/) (63/502 passed, $3.29) · [Job Posting Screen](https://futuresearch.ai/job-posting-screening/) (>90% vs 68% regex) · [Lead Screening Workflow](https://futuresearch.ai/screening-workflow/)
|
|
153
|
+
|
|
154
|
+
[Full documentation →](docs/SCREEN.md)
|
|
155
|
+
|
|
156
|
+
### Agent Tasks
|
|
157
|
+
|
|
158
|
+
For single-input tasks, use `single_agent`. For batch processing, use `agent_map`.
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from everyrow.ops import single_agent, agent_map
|
|
162
|
+
from pandas import DataFrame
|
|
163
|
+
|
|
164
|
+
# Single input
|
|
165
|
+
result = await single_agent(
|
|
166
|
+
task="What is the capital of the given country?",
|
|
167
|
+
input={"country": "India"},
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
# Batch processing
|
|
171
|
+
result = await agent_map(
|
|
172
|
+
task="What is the capital of the given country?",
|
|
173
|
+
input=DataFrame([{"country": "India"}, {"country": "USA"}]),
|
|
174
|
+
)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Our agents are tuned on [Deep Research Bench](https://arxiv.org/abs/2506.06287), a benchmark we built for evaluating web research on questions that require extensive searching and cross-referencing.
|
|
178
|
+
|
|
179
|
+
## Advanced
|
|
180
|
+
|
|
181
|
+
### Sessions
|
|
182
|
+
|
|
183
|
+
For quick one-off operations, sessions are created automatically:
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
from everyrow.ops import single_agent
|
|
187
|
+
|
|
188
|
+
result = await single_agent(
|
|
189
|
+
task="What is the capital of France?",
|
|
190
|
+
input={"country": "France"},
|
|
191
|
+
)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
For multiple operations, use an explicit session:
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from everyrow import create_session
|
|
198
|
+
|
|
199
|
+
async with create_session(name="My Session") as session:
|
|
200
|
+
print(f"View session at: {session.get_url()}")
|
|
201
|
+
# All operations here share the same session
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
If you want more explicit control over the client (for example, to reuse it across sessions or configure custom settings), you can create it directly:
|
|
205
|
+
|
|
206
|
+
```python
|
|
207
|
+
from everyrow import create_client, create_session
|
|
208
|
+
|
|
209
|
+
async with create_client() as client:
|
|
210
|
+
async with create_session(client=client, name="My Session") as session:
|
|
211
|
+
# ...
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Sessions are visible on the [everyrow.io](https://everyrow.io) dashboard.
|
|
215
|
+
|
|
216
|
+
### Async Operations
|
|
217
|
+
|
|
218
|
+
All utilities have async variants for background processing. These need an explicit session since the task persists beyond the function call:
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
from everyrow import create_session
|
|
222
|
+
from everyrow.ops import rank_async
|
|
223
|
+
|
|
224
|
+
async with create_session(name="Async Ranking") as session:
|
|
225
|
+
task = await rank_async(
|
|
226
|
+
session=session,
|
|
227
|
+
task="Score this organization",
|
|
228
|
+
input=dataframe,
|
|
229
|
+
field_name="score",
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# Continue with other work...
|
|
233
|
+
result = await task.await_result()
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Case Studies
|
|
237
|
+
|
|
238
|
+
More at [futuresearch.ai/solutions](https://futuresearch.ai/solutions/).
|
|
239
|
+
|
|
240
|
+
**Notebooks:**
|
|
241
|
+
- [CRM Deduplication](case_studies/dedupe/case_01_crm_data.ipynb)
|
|
242
|
+
- [Thematic Stock Screen](case_studies/screen/thematic_stock_screen.ipynb)
|
|
243
|
+
- [Oil Price Margin Screen](case_studies/screen/oil_price_margin_screen.ipynb)
|
|
244
|
+
|
|
245
|
+
**On futuresearch.ai:**
|
|
246
|
+
- [Lead Scoring with Data Fragmentation](https://futuresearch.ai/lead-scoring-data-fragmentation/)
|
|
247
|
+
- [Software Supplier Matching](https://futuresearch.ai/software-supplier-matching/)
|
|
248
|
+
- [Researcher Deduplication](https://futuresearch.ai/researcher-dedupe-case-study/)
|
|
249
|
+
|
|
250
|
+
To run notebooks:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
uv sync --group case-studies
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## Development
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
uv sync
|
|
260
|
+
lefthook install
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
uv run pytest # tests
|
|
265
|
+
uv run ruff check . # lint
|
|
266
|
+
uv run ruff format . # format
|
|
267
|
+
uv run basedpyright # type check
|
|
268
|
+
./generate_openapi.sh # regenerate client
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
The `everyrow/generated/` directory is excluded from linting (auto-generated code).
|
|
272
|
+
|
|
273
|
+
## License
|
|
274
|
+
|
|
275
|
+
This project is licensed under the MIT License - see LICENSE.txt file for details.
|
everyrow-0.1.1/README.md
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# <picture><img src="images/future-search-logo-128.webp" alt="FutureSearch" height="24" align="bottom"></picture> everyrow SDK
|
|
4
|
+
|
|
5
|
+
Python SDK for [everyrow.io](https://everyrow.io). Rank, dedupe, merge, and screen your dataframes using natural language—or run web agents to research every row.
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
New to everyrow? Head to [Getting Started](#getting-started)
|
|
10
|
+
|
|
11
|
+
Looking to use our agent-backed utilities? Check out:
|
|
12
|
+
- [Rank](#rank)
|
|
13
|
+
- [Dedupe](#dedupe)
|
|
14
|
+
- [Merge](#merge)
|
|
15
|
+
- [Screen](#screen)
|
|
16
|
+
- [Agent Tasks](#agent-tasks)
|
|
17
|
+
|
|
18
|
+
## Getting Started
|
|
19
|
+
|
|
20
|
+
Get an API key at [everyrow.io](https://everyrow.io).
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
export EVERYROW_API_KEY=your_api_key_here
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install everyrow
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
For development:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
uv pip install -e .
|
|
36
|
+
uv sync
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Requires Python >= 3.12
|
|
40
|
+
|
|
41
|
+
### Claude Code Plugin
|
|
42
|
+
|
|
43
|
+
There's a plugin for [Claude Code](https://code.claude.com/) that teaches Claude how to use the SDK:
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
# from Claude Code
|
|
47
|
+
/plugin marketplace add futuresearch/everyrow-sdk
|
|
48
|
+
/plugin install everyrow@futuresearch
|
|
49
|
+
|
|
50
|
+
# from terminal
|
|
51
|
+
claude plugin marketplace add futuresearch/everyrow-sdk
|
|
52
|
+
claude plugin install everyrow@futuresearch
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Rank
|
|
56
|
+
|
|
57
|
+
Score rows based on criteria you can't put in a database field. The AI researches each row and assigns scores based on qualitative factors.
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from everyrow.ops import rank
|
|
61
|
+
|
|
62
|
+
result = await rank(
|
|
63
|
+
task="Score by likelihood to need data integration solutions",
|
|
64
|
+
input=leads_dataframe,
|
|
65
|
+
field_name="integration_need_score",
|
|
66
|
+
)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Say you want to rank leads by "likelihood to need data integration tools"—Ultramain Systems (sells software to airlines) looks similar to Ukraine International Airlines (is an airline) by industry code, but their actual needs are completely different. Traditional scoring can't tell them apart.
|
|
70
|
+
|
|
71
|
+
**Case studies:** [Lead Scoring with Data Fragmentation](https://futuresearch.ai/lead-scoring-data-fragmentation/) (1,000 leads, 7 min, $13) · [Lead Scoring Without CRM](https://futuresearch.ai/lead-scoring-without-crm/) ($28 vs $145 with Clay)
|
|
72
|
+
|
|
73
|
+
[Full documentation →](docs/RANK.md)
|
|
74
|
+
|
|
75
|
+
### Dedupe
|
|
76
|
+
|
|
77
|
+
Deduplicate when fuzzy matching falls short. The AI understands that "AbbVie Inc", "Abbvie", and "AbbVie Pharmaceutical" are the same company, or that "Big Blue" means IBM.
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from everyrow.ops import dedupe
|
|
81
|
+
|
|
82
|
+
result = await dedupe(
|
|
83
|
+
input=crm_data,
|
|
84
|
+
equivalence_relation="Two entries are duplicates if they represent the same legal entity",
|
|
85
|
+
)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The `equivalence_relation` tells the AI what counts as a duplicate—natural language, not regex. Results include `equivalence_class_id` (groups duplicates), `equivalence_class_name` (human-readable cluster name), and `selected` (the canonical record in each cluster).
|
|
89
|
+
|
|
90
|
+
**Case studies:** [CRM Deduplication](https://futuresearch.ai/crm-deduplication/) (500→124 rows, 2 min, $1.67) · [Researcher Deduplication](https://futuresearch.ai/researcher-dedupe-case-study/) (98% accuracy with career changes)
|
|
91
|
+
|
|
92
|
+
[Full documentation →](docs/DEDUPE.md)
|
|
93
|
+
|
|
94
|
+
### Merge
|
|
95
|
+
|
|
96
|
+
Join two tables when the keys don't match exactly—or at all. The AI knows "Photoshop" belongs to "Adobe" and "Genentech" is a Roche subsidiary, even with zero string similarity.
|
|
97
|
+
|
|
98
|
+
```python
|
|
99
|
+
from everyrow.ops import merge
|
|
100
|
+
|
|
101
|
+
result = await merge(
|
|
102
|
+
task="Match each software product to its parent company",
|
|
103
|
+
left_table=software_products,
|
|
104
|
+
right_table=approved_suppliers,
|
|
105
|
+
merge_on_left="software_name",
|
|
106
|
+
merge_on_right="company_name",
|
|
107
|
+
)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Handles subsidiaries, abbreviations (MSD → Merck), regional names, typos, and pseudonyms. Fuzzy matching thresholds always fail somewhere—0.9 misses "Colfi" ↔ "Dr. Ioana Colfescu", 0.7 false-positives on "John Smith" ↔ "Jane Smith".
|
|
111
|
+
|
|
112
|
+
**Case studies:** [Software Supplier Matching](https://futuresearch.ai/software-supplier-matching/) (2,000 products, 91% accuracy, $9) · [HubSpot Contact Merge](https://futuresearch.ai/merge-hubspot-contacts/) (99.9% recall) · [CRM Merge Workflow](https://futuresearch.ai/crm-merge-workflow/)
|
|
113
|
+
|
|
114
|
+
[Full documentation →](docs/MERGE.md)
|
|
115
|
+
|
|
116
|
+
### Screen
|
|
117
|
+
|
|
118
|
+
Filter rows based on criteria that require research—things you can't express in SQL. The AI actually researches each row (10-Ks, earnings reports, news) before deciding pass/fail.
|
|
119
|
+
|
|
120
|
+
```python
|
|
121
|
+
from everyrow.ops import screen
|
|
122
|
+
from pydantic import BaseModel, Field
|
|
123
|
+
|
|
124
|
+
class ScreenResult(BaseModel):
|
|
125
|
+
passes: bool = Field(description="True if company meets the criteria")
|
|
126
|
+
|
|
127
|
+
result = await screen(
|
|
128
|
+
task="""
|
|
129
|
+
Find companies with >75% recurring revenue that would benefit from
|
|
130
|
+
Taiwan tensions - CHIPS Act beneficiaries, defense contractors,
|
|
131
|
+
cybersecurity firms. Exclude companies dependent on Taiwan manufacturing.
|
|
132
|
+
""",
|
|
133
|
+
input=sp500_companies,
|
|
134
|
+
response_model=ScreenResult,
|
|
135
|
+
)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Works for investment theses, geopolitical exposure, vendor risk assessment, job posting filtering, lead qualification—anything requiring judgment. Screening 500 S&P 500 companies takes ~12 min and $3 with >90% precision. Regex gets 68%.
|
|
139
|
+
|
|
140
|
+
**Case studies:** [Thematic Stock Screen](https://futuresearch.ai/thematic-stock-screening/) (63/502 passed, $3.29) · [Job Posting Screen](https://futuresearch.ai/job-posting-screening/) (>90% vs 68% regex) · [Lead Screening Workflow](https://futuresearch.ai/screening-workflow/)
|
|
141
|
+
|
|
142
|
+
[Full documentation →](docs/SCREEN.md)
|
|
143
|
+
|
|
144
|
+
### Agent Tasks
|
|
145
|
+
|
|
146
|
+
For single-input tasks, use `single_agent`. For batch processing, use `agent_map`.
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from everyrow.ops import single_agent, agent_map
|
|
150
|
+
from pandas import DataFrame
|
|
151
|
+
|
|
152
|
+
# Single input
|
|
153
|
+
result = await single_agent(
|
|
154
|
+
task="What is the capital of the given country?",
|
|
155
|
+
input={"country": "India"},
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
# Batch processing
|
|
159
|
+
result = await agent_map(
|
|
160
|
+
task="What is the capital of the given country?",
|
|
161
|
+
input=DataFrame([{"country": "India"}, {"country": "USA"}]),
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Our agents are tuned on [Deep Research Bench](https://arxiv.org/abs/2506.06287), a benchmark we built for evaluating web research on questions that require extensive searching and cross-referencing.
|
|
166
|
+
|
|
167
|
+
## Advanced
|
|
168
|
+
|
|
169
|
+
### Sessions
|
|
170
|
+
|
|
171
|
+
For quick one-off operations, sessions are created automatically:
|
|
172
|
+
|
|
173
|
+
```python
|
|
174
|
+
from everyrow.ops import single_agent
|
|
175
|
+
|
|
176
|
+
result = await single_agent(
|
|
177
|
+
task="What is the capital of France?",
|
|
178
|
+
input={"country": "France"},
|
|
179
|
+
)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
For multiple operations, use an explicit session:
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from everyrow import create_session
|
|
186
|
+
|
|
187
|
+
async with create_session(name="My Session") as session:
|
|
188
|
+
print(f"View session at: {session.get_url()}")
|
|
189
|
+
# All operations here share the same session
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
If you want more explicit control over the client (for example, to reuse it across sessions or configure custom settings), you can create it directly:
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
from everyrow import create_client, create_session
|
|
196
|
+
|
|
197
|
+
async with create_client() as client:
|
|
198
|
+
async with create_session(client=client, name="My Session") as session:
|
|
199
|
+
# ...
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Sessions are visible on the [everyrow.io](https://everyrow.io) dashboard.
|
|
203
|
+
|
|
204
|
+
### Async Operations
|
|
205
|
+
|
|
206
|
+
All utilities have async variants for background processing. These need an explicit session since the task persists beyond the function call:
|
|
207
|
+
|
|
208
|
+
```python
|
|
209
|
+
from everyrow import create_session
|
|
210
|
+
from everyrow.ops import rank_async
|
|
211
|
+
|
|
212
|
+
async with create_session(name="Async Ranking") as session:
|
|
213
|
+
task = await rank_async(
|
|
214
|
+
session=session,
|
|
215
|
+
task="Score this organization",
|
|
216
|
+
input=dataframe,
|
|
217
|
+
field_name="score",
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
# Continue with other work...
|
|
221
|
+
result = await task.await_result()
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Case Studies
|
|
225
|
+
|
|
226
|
+
More at [futuresearch.ai/solutions](https://futuresearch.ai/solutions/).
|
|
227
|
+
|
|
228
|
+
**Notebooks:**
|
|
229
|
+
- [CRM Deduplication](case_studies/dedupe/case_01_crm_data.ipynb)
|
|
230
|
+
- [Thematic Stock Screen](case_studies/screen/thematic_stock_screen.ipynb)
|
|
231
|
+
- [Oil Price Margin Screen](case_studies/screen/oil_price_margin_screen.ipynb)
|
|
232
|
+
|
|
233
|
+
**On futuresearch.ai:**
|
|
234
|
+
- [Lead Scoring with Data Fragmentation](https://futuresearch.ai/lead-scoring-data-fragmentation/)
|
|
235
|
+
- [Software Supplier Matching](https://futuresearch.ai/software-supplier-matching/)
|
|
236
|
+
- [Researcher Deduplication](https://futuresearch.ai/researcher-dedupe-case-study/)
|
|
237
|
+
|
|
238
|
+
To run notebooks:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
uv sync --group case-studies
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
## Development
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
uv sync
|
|
248
|
+
lefthook install
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
uv run pytest # tests
|
|
253
|
+
uv run ruff check . # lint
|
|
254
|
+
uv run ruff format . # format
|
|
255
|
+
uv run basedpyright # type check
|
|
256
|
+
./generate_openapi.sh # regenerate client
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The `everyrow/generated/` directory is excluded from linting (auto-generated code).
|
|
260
|
+
|
|
261
|
+
## License
|
|
262
|
+
|
|
263
|
+
This project is licensed under the MIT License - see LICENSE.txt file for details.
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"execution_count": null,
|
|
24
24
|
"metadata": {},
|
|
25
25
|
"outputs": [],
|
|
26
|
-
"source": "from datetime import datetime\nfrom textwrap import dedent\n\nimport pandas as pd\nfrom dotenv import load_dotenv\n\nfrom everyrow
|
|
26
|
+
"source": "from datetime import datetime\nfrom textwrap import dedent\n\nimport pandas as pd\nfrom dotenv import load_dotenv\n\nfrom everyrow.ops import dedupe\n\nload_dotenv()"
|
|
27
27
|
},
|
|
28
28
|
{
|
|
29
29
|
"cell_type": "markdown",
|
|
@@ -222,34 +222,8 @@
|
|
|
222
222
|
"cell_type": "code",
|
|
223
223
|
"execution_count": null,
|
|
224
224
|
"metadata": {},
|
|
225
|
-
"outputs": [
|
|
226
|
-
|
|
227
|
-
"name": "stdout",
|
|
228
|
-
"output_type": "stream",
|
|
229
|
-
"text": [
|
|
230
|
-
"Session URL: https://everyrow.io/sessions/912cde86-8f35-4381-95a2-7bf1e68bb4f6\n",
|
|
231
|
-
"Deduplicating CRM data...\n",
|
|
232
|
-
"\n"
|
|
233
|
-
]
|
|
234
|
-
}
|
|
235
|
-
],
|
|
236
|
-
"source": [
|
|
237
|
-
"equivalence_relation = dedent(\"\"\"\n",
|
|
238
|
-
" Two entries are duplicates if they include data for the same legal entity.\n",
|
|
239
|
-
"\"\"\")\n",
|
|
240
|
-
"\n",
|
|
241
|
-
"async with create_client() as client:\n",
|
|
242
|
-
" session_name = f\"CRM Deduplication {datetime.now().isoformat()}\"\n",
|
|
243
|
-
" async with create_session(client=client, name=session_name) as session:\n",
|
|
244
|
-
" print(f\"Session URL: {session.get_url()}\")\n",
|
|
245
|
-
" print(\"Deduplicating CRM data...\\n\")\n",
|
|
246
|
-
"\n",
|
|
247
|
-
" result = await dedupe(\n",
|
|
248
|
-
" session=session,\n",
|
|
249
|
-
" input=data,\n",
|
|
250
|
-
" equivalence_relation=equivalence_relation,\n",
|
|
251
|
-
" )"
|
|
252
|
-
]
|
|
225
|
+
"outputs": [],
|
|
226
|
+
"source": "equivalence_relation = dedent(\"\"\"\n Two entries are duplicates if they include data for the same legal entity.\n\"\"\")\n\nprint(\"Deduplicating CRM data...\\n\")\n\nresult = await dedupe(\n input=data,\n equivalence_relation=equivalence_relation,\n)"
|
|
253
227
|
},
|
|
254
228
|
{
|
|
255
229
|
"cell_type": "markdown",
|