diff --git a/.github/actions/run-and-record-tests/action.yml b/.github/actions/run-and-record-tests/action.yml index a5aa31af4..ac600d570 100644 --- a/.github/actions/run-and-record-tests/action.yml +++ b/.github/actions/run-and-record-tests/action.yml @@ -82,11 +82,13 @@ runs: echo "No recording changes" fi - - name: Write inference logs to file + - name: Write docker logs to file if: ${{ always() }} shell: bash run: | - sudo docker logs ollama > ollama-${{ inputs.inference-mode }}.log || true + # Ollama logs (if ollama container exists) + sudo docker logs ollama > ollama-${{ inputs.inference-mode }}.log 2>&1 || true + # Note: distro container logs are now dumped in integration-tests.sh before container is removed - name: Upload logs if: ${{ always() }} diff --git a/.github/workflows/integration-auth-tests.yml b/.github/workflows/integration-auth-tests.yml index ea3ff2b64..30a8063ea 100644 --- a/.github/workflows/integration-auth-tests.yml +++ b/.github/workflows/integration-auth-tests.yml @@ -73,6 +73,24 @@ jobs: image_name: kube apis: [] providers: {} + storage: + backends: + kv_default: + type: kv_sqlite + db_path: $run_dir/kvstore.db + sql_default: + type: sql_sqlite + db_path: $run_dir/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + conversations: + table_name: openai_conversations + backend: sql_default server: port: 8321 EOF diff --git a/.github/workflows/integration-vector-io-tests.yml b/.github/workflows/integration-vector-io-tests.yml index e9a758873..a6a86b15f 100644 --- a/.github/workflows/integration-vector-io-tests.yml +++ b/.github/workflows/integration-vector-io-tests.yml @@ -169,9 +169,7 @@ jobs: run: | uv run --no-sync \ pytest -sv --stack-config="files=inline::localfs,inference=inline::sentence-transformers,vector_io=${{ matrix.vector-io-provider }}" \ - tests/integration/vector_io \ - --embedding-model inline::sentence-transformers/nomic-ai/nomic-embed-text-v1.5 \ - --embedding-dimension 768 + tests/integration/vector_io - name: Check Storage and Memory Available After Tests if: ${{ always() }} diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index b5845be53..0fdd50acc 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -37,7 +37,7 @@ jobs: .pre-commit-config.yaml - name: Set up Node.js - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 with: node-version: '20' cache: 'npm' diff --git a/.github/workflows/precommit-trigger.yml b/.github/workflows/precommit-trigger.yml index 0c23b57de..b05898d29 100644 --- a/.github/workflows/precommit-trigger.yml +++ b/.github/workflows/precommit-trigger.yml @@ -99,7 +99,7 @@ jobs: owner: context.repo.owner, repo: context.repo.repo, issue_number: ${{ steps.check_author.outputs.pr_number }}, - body: `⏳ Running pre-commit hooks on PR #${{ steps.check_author.outputs.pr_number }}...` + body: `⏳ Running [pre-commit hooks](https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}) on PR #${{ steps.check_author.outputs.pr_number }}...` }); - name: Checkout PR branch (same-repo) @@ -141,7 +141,7 @@ jobs: - name: Set up Node.js if: steps.check_author.outputs.authorized == 'true' - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 with: node-version: '20' cache: 'npm' diff --git a/.github/workflows/providers-list-deps.yml b/.github/workflows/providers-list-deps.yml index df491b680..e30e1e5fb 100644 --- a/.github/workflows/providers-list-deps.yml +++ b/.github/workflows/providers-list-deps.yml @@ -36,7 +36,7 @@ jobs: distros: ${{ steps.set-matrix.outputs.distros }} steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Generate Distribution List id: set-matrix @@ -55,7 +55,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Install dependencies uses: ./.github/actions/setup-runner @@ -79,7 +79,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Install dependencies uses: ./.github/actions/setup-runner @@ -92,7 +92,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Install dependencies uses: ./.github/actions/setup-runner diff --git a/.github/workflows/python-build-test.yml b/.github/workflows/python-build-test.yml index dfa844175..96243285f 100644 --- a/.github/workflows/python-build-test.yml +++ b/.github/workflows/python-build-test.yml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Install uv - uses: astral-sh/setup-uv@eb1897b8dc4b5d5bfe39a428a8f2304605e0983c # v7.0.0 + uses: astral-sh/setup-uv@3259c6206f993105e3a61b142c2d97bf4b9ef83d # v7.1.0 with: python-version: ${{ matrix.python-version }} activate-environment: true diff --git a/.github/workflows/ui-unit-tests.yml b/.github/workflows/ui-unit-tests.yml index c16f512d1..e8f318b8e 100644 --- a/.github/workflows/ui-unit-tests.yml +++ b/.github/workflows/ui-unit-tests.yml @@ -29,7 +29,7 @@ jobs: uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Setup Node.js - uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0 + uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 # v6.0.0 with: node-version: ${{ matrix.node-version }} cache: 'npm' diff --git a/benchmarking/k8s-benchmark/stack-configmap.yaml b/benchmarking/k8s-benchmark/stack-configmap.yaml index bb8a48d65..e1ca170f5 100644 --- a/benchmarking/k8s-benchmark/stack-configmap.yaml +++ b/benchmarking/k8s-benchmark/stack-configmap.yaml @@ -98,21 +98,30 @@ data: - provider_id: model-context-protocol provider_type: remote::model-context-protocol config: {} - metadata_store: - type: postgres - host: ${env.POSTGRES_HOST:=localhost} - port: ${env.POSTGRES_PORT:=5432} - db: ${env.POSTGRES_DB:=llamastack} - user: ${env.POSTGRES_USER:=llamastack} - password: ${env.POSTGRES_PASSWORD:=llamastack} - table_name: llamastack_kvstore - inference_store: - type: postgres - host: ${env.POSTGRES_HOST:=localhost} - port: ${env.POSTGRES_PORT:=5432} - db: ${env.POSTGRES_DB:=llamastack} - user: ${env.POSTGRES_USER:=llamastack} - password: ${env.POSTGRES_PASSWORD:=llamastack} + storage: + backends: + kv_default: + type: kv_postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + table_name: ${env.POSTGRES_TABLE_NAME:=llamastack_kvstore} + sql_default: + type: sql_postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + references: + metadata: + backend: kv_default + namespace: registry + inference: + backend: sql_default + table_name: inference_store models: - metadata: embedding_dimension: 768 @@ -137,5 +146,4 @@ data: port: 8323 kind: ConfigMap metadata: - creationTimestamp: null name: llama-stack-config diff --git a/benchmarking/k8s-benchmark/stack_run_config.yaml b/benchmarking/k8s-benchmark/stack_run_config.yaml index e2fbfd7a4..2ccaa21aa 100644 --- a/benchmarking/k8s-benchmark/stack_run_config.yaml +++ b/benchmarking/k8s-benchmark/stack_run_config.yaml @@ -95,21 +95,30 @@ providers: - provider_id: model-context-protocol provider_type: remote::model-context-protocol config: {} -metadata_store: - type: postgres - host: ${env.POSTGRES_HOST:=localhost} - port: ${env.POSTGRES_PORT:=5432} - db: ${env.POSTGRES_DB:=llamastack} - user: ${env.POSTGRES_USER:=llamastack} - password: ${env.POSTGRES_PASSWORD:=llamastack} - table_name: llamastack_kvstore -inference_store: - type: postgres - host: ${env.POSTGRES_HOST:=localhost} - port: ${env.POSTGRES_PORT:=5432} - db: ${env.POSTGRES_DB:=llamastack} - user: ${env.POSTGRES_USER:=llamastack} - password: ${env.POSTGRES_PASSWORD:=llamastack} +storage: + backends: + kv_default: + type: kv_postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + table_name: ${env.POSTGRES_TABLE_NAME:=llamastack_kvstore} + sql_default: + type: sql_postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + references: + metadata: + backend: kv_default + namespace: registry + inference: + backend: sql_default + table_name: inference_store models: - metadata: embedding_dimension: 768 diff --git a/client-sdks/stainless/README.md b/client-sdks/stainless/README.md new file mode 100644 index 000000000..5d391f14c --- /dev/null +++ b/client-sdks/stainless/README.md @@ -0,0 +1,8 @@ +These are the source-of-truth configuration files used to generate the Stainless client SDKs via Stainless. + +- `openapi.yml`: this is the OpenAPI specification for the Llama Stack API. +- `openapi.stainless.yml`: this is the Stainless _configuration_ which instructs Stainless how to generate the client SDKs. + +A small side note: notice the `.yml` suffixes since Stainless uses that suffix typically for its configuration files. + +These files go hand-in-hand. As of now, only the `openapi.yml` file is automatically generated using the `run_openapi_generator.sh` script. \ No newline at end of file diff --git a/client-sdks/stainless/openapi.stainless.yml b/client-sdks/stainless/openapi.stainless.yml new file mode 100644 index 000000000..9461be996 --- /dev/null +++ b/client-sdks/stainless/openapi.stainless.yml @@ -0,0 +1,610 @@ +# yaml-language-server: $schema=https://app.stainlessapi.com/config-internal.schema.json + +organization: + # Name of your organization or company, used to determine the name of the client + # and headings. + name: llama-stack-client + docs: https://llama-stack.readthedocs.io/en/latest/ + contact: llamastack@meta.com +security: + - {} + - BearerAuth: [] +security_schemes: + BearerAuth: + type: http + scheme: bearer +# `targets` define the output targets and their customization options, such as +# whether to emit the Node SDK and what it's package name should be. +targets: + node: + package_name: llama-stack-client + production_repo: llamastack/llama-stack-client-typescript + publish: + npm: false + python: + package_name: llama_stack_client + production_repo: llamastack/llama-stack-client-python + options: + use_uv: true + publish: + pypi: true + project_name: llama_stack_client + kotlin: + reverse_domain: com.llama_stack_client.api + production_repo: null + publish: + maven: false + go: + package_name: llama-stack-client + production_repo: llamastack/llama-stack-client-go + options: + enable_v2: true + back_compat_use_shared_package: false + +# `client_settings` define settings for the API client, such as extra constructor +# arguments (used for authentication), retry behavior, idempotency, etc. +client_settings: + default_env_prefix: LLAMA_STACK_CLIENT + opts: + api_key: + type: string + read_env: LLAMA_STACK_CLIENT_API_KEY + auth: { security_scheme: BearerAuth } + nullable: true + +# `environments` are a map of the name of the environment (e.g. "sandbox", +# "production") to the corresponding url to use. +environments: + production: http://any-hosted-llama-stack.com + +# `pagination` defines [pagination schemes] which provides a template to match +# endpoints and generate next-page and auto-pagination helpers in the SDKs. +pagination: + - name: datasets_iterrows + type: offset + request: + dataset_id: + type: string + start_index: + type: integer + x-stainless-pagination-property: + purpose: offset_count_param + limit: + type: integer + response: + data: + type: array + items: + type: object + next_index: + type: integer + x-stainless-pagination-property: + purpose: offset_count_start_field + - name: openai_cursor_page + type: cursor + request: + limit: + type: integer + after: + type: string + x-stainless-pagination-property: + purpose: next_cursor_param + response: + data: + type: array + items: {} + has_more: + type: boolean + last_id: + type: string + x-stainless-pagination-property: + purpose: next_cursor_field +# `resources` define the structure and organziation for your API, such as how +# methods and models are grouped together and accessed. See the [configuration +# guide] for more information. +# +# [configuration guide]: +# https://app.stainlessapi.com/docs/guides/configure#resources +resources: + $shared: + models: + agent_config: AgentConfig + interleaved_content_item: InterleavedContentItem + interleaved_content: InterleavedContent + param_type: ParamType + safety_violation: SafetyViolation + sampling_params: SamplingParams + scoring_result: ScoringResult + message: Message + user_message: UserMessage + completion_message: CompletionMessage + tool_response_message: ToolResponseMessage + system_message: SystemMessage + tool_call: ToolCall + query_result: RAGQueryResult + document: RAGDocument + query_config: RAGQueryConfig + response_format: ResponseFormat + toolgroups: + models: + tool_group: ToolGroup + list_tool_groups_response: ListToolGroupsResponse + methods: + register: post /v1/toolgroups + get: get /v1/toolgroups/{toolgroup_id} + list: get /v1/toolgroups + unregister: delete /v1/toolgroups/{toolgroup_id} + tools: + methods: + get: get /v1/tools/{tool_name} + list: + endpoint: get /v1/tools + paginated: false + + tool_runtime: + models: + tool_def: ToolDef + tool_invocation_result: ToolInvocationResult + methods: + list_tools: + endpoint: get /v1/tool-runtime/list-tools + paginated: false + invoke_tool: post /v1/tool-runtime/invoke + subresources: + rag_tool: + methods: + insert: post /v1/tool-runtime/rag-tool/insert + query: post /v1/tool-runtime/rag-tool/query + + responses: + models: + response_object_stream: OpenAIResponseObjectStream + response_object: OpenAIResponseObject + methods: + create: + type: http + endpoint: post /v1/responses + streaming: + stream_event_model: responses.response_object_stream + param_discriminator: stream + retrieve: get /v1/responses/{response_id} + list: + type: http + endpoint: get /v1/responses + delete: + type: http + endpoint: delete /v1/responses/{response_id} + subresources: + input_items: + methods: + list: + type: http + endpoint: get /v1/responses/{response_id}/input_items + + conversations: + models: + conversation_object: Conversation + methods: + create: + type: http + endpoint: post /v1/conversations + retrieve: get /v1/conversations/{conversation_id} + update: + type: http + endpoint: post /v1/conversations/{conversation_id} + delete: + type: http + endpoint: delete /v1/conversations/{conversation_id} + subresources: + items: + methods: + get: + type: http + endpoint: get /v1/conversations/{conversation_id}/items/{item_id} + list: + type: http + endpoint: get /v1/conversations/{conversation_id}/items + create: + type: http + endpoint: post /v1/conversations/{conversation_id}/items + + inspect: + models: + healthInfo: HealthInfo + providerInfo: ProviderInfo + routeInfo: RouteInfo + versionInfo: VersionInfo + methods: + health: get /v1/health + version: get /v1/version + + embeddings: + models: + create_embeddings_response: OpenAIEmbeddingsResponse + methods: + create: post /v1/embeddings + + chat: + models: + chat_completion_chunk: OpenAIChatCompletionChunk + subresources: + completions: + methods: + create: + type: http + endpoint: post /v1/chat/completions + streaming: + stream_event_model: chat.chat_completion_chunk + param_discriminator: stream + list: + type: http + endpoint: get /v1/chat/completions + retrieve: + type: http + endpoint: get /v1/chat/completions/{completion_id} + completions: + methods: + create: + type: http + endpoint: post /v1/completions + streaming: + param_discriminator: stream + + vector_io: + models: + queryChunksResponse: QueryChunksResponse + methods: + insert: post /v1/vector-io/insert + query: post /v1/vector-io/query + + vector_stores: + models: + vector_store: VectorStoreObject + list_vector_stores_response: VectorStoreListResponse + vector_store_delete_response: VectorStoreDeleteResponse + vector_store_search_response: VectorStoreSearchResponsePage + methods: + create: post /v1/vector_stores + list: + endpoint: get /v1/vector_stores + retrieve: get /v1/vector_stores/{vector_store_id} + update: post /v1/vector_stores/{vector_store_id} + delete: delete /v1/vector_stores/{vector_store_id} + search: post /v1/vector_stores/{vector_store_id}/search + subresources: + files: + models: + vector_store_file: VectorStoreFileObject + methods: + list: get /v1/vector_stores/{vector_store_id}/files + retrieve: get /v1/vector_stores/{vector_store_id}/files/{file_id} + update: post /v1/vector_stores/{vector_store_id}/files/{file_id} + delete: delete /v1/vector_stores/{vector_store_id}/files/{file_id} + create: post /v1/vector_stores/{vector_store_id}/files + content: get /v1/vector_stores/{vector_store_id}/files/{file_id}/content + file_batches: + models: + vector_store_file_batches: VectorStoreFileBatchObject + list_vector_store_files_in_batch_response: VectorStoreFilesListInBatchResponse + methods: + create: post /v1/vector_stores/{vector_store_id}/file_batches + retrieve: get /v1/vector_stores/{vector_store_id}/file_batches/{batch_id} + list_files: get /v1/vector_stores/{vector_store_id}/file_batches/{batch_id}/files + cancel: post /v1/vector_stores/{vector_store_id}/file_batches/{batch_id}/cancel + + models: + models: + model: Model + list_models_response: ListModelsResponse + methods: + retrieve: get /v1/models/{model_id} + list: + endpoint: get /v1/models + paginated: false + register: post /v1/models + unregister: delete /v1/models/{model_id} + subresources: + openai: + methods: + list: + endpoint: get /v1/models + paginated: false + + providers: + models: + list_providers_response: ListProvidersResponse + methods: + list: + endpoint: get /v1/providers + paginated: false + retrieve: get /v1/providers/{provider_id} + + routes: + models: + list_routes_response: ListRoutesResponse + methods: + list: + endpoint: get /v1/inspect/routes + paginated: false + + + moderations: + models: + create_response: ModerationObject + methods: + create: post /v1/moderations + + + safety: + models: + run_shield_response: RunShieldResponse + methods: + run_shield: post /v1/safety/run-shield + + + shields: + models: + shield: Shield + list_shields_response: ListShieldsResponse + methods: + retrieve: get /v1/shields/{identifier} + list: + endpoint: get /v1/shields + paginated: false + register: post /v1/shields + delete: delete /v1/shields/{identifier} + + synthetic_data_generation: + models: + syntheticDataGenerationResponse: SyntheticDataGenerationResponse + methods: + generate: post /v1/synthetic-data-generation/generate + + telemetry: + models: + span_with_status: SpanWithStatus + trace: Trace + query_spans_response: QuerySpansResponse + event: Event + query_condition: QueryCondition + methods: + query_traces: + endpoint: post /v1alpha/telemetry/traces + skip_test_reason: 'unsupported query params in java / kotlin' + get_span_tree: post /v1alpha/telemetry/spans/{span_id}/tree + query_spans: + endpoint: post /v1alpha/telemetry/spans + skip_test_reason: 'unsupported query params in java / kotlin' + query_metrics: + endpoint: post /v1alpha/telemetry/metrics/{metric_name} + skip_test_reason: 'unsupported query params in java / kotlin' + # log_event: post /v1alpha/telemetry/events + save_spans_to_dataset: post /v1alpha/telemetry/spans/export + get_span: get /v1alpha/telemetry/traces/{trace_id}/spans/{span_id} + get_trace: get /v1alpha/telemetry/traces/{trace_id} + + scoring: + methods: + score: post /v1/scoring/score + score_batch: post /v1/scoring/score-batch + scoring_functions: + methods: + retrieve: get /v1/scoring-functions/{scoring_fn_id} + list: + endpoint: get /v1/scoring-functions + paginated: false + register: post /v1/scoring-functions + models: + scoring_fn: ScoringFn + scoring_fn_params: ScoringFnParams + list_scoring_functions_response: ListScoringFunctionsResponse + + benchmarks: + methods: + retrieve: get /v1alpha/eval/benchmarks/{benchmark_id} + list: + endpoint: get /v1alpha/eval/benchmarks + paginated: false + register: post /v1alpha/eval/benchmarks + models: + benchmark: Benchmark + list_benchmarks_response: ListBenchmarksResponse + + files: + methods: + create: post /v1/files + list: get /v1/files + retrieve: get /v1/files/{file_id} + delete: delete /v1/files/{file_id} + content: get /v1/files/{file_id}/content + models: + file: OpenAIFileObject + list_files_response: ListOpenAIFileResponse + delete_file_response: OpenAIFileDeleteResponse + + alpha: + subresources: + inference: + methods: + rerank: post /v1alpha/inference/rerank + + post_training: + models: + algorithm_config: AlgorithmConfig + post_training_job: PostTrainingJob + list_post_training_jobs_response: ListPostTrainingJobsResponse + methods: + preference_optimize: post /v1alpha/post-training/preference-optimize + supervised_fine_tune: post /v1alpha/post-training/supervised-fine-tune + subresources: + job: + methods: + artifacts: get /v1alpha/post-training/job/artifacts + cancel: post /v1alpha/post-training/job/cancel + status: get /v1alpha/post-training/job/status + list: + endpoint: get /v1alpha/post-training/jobs + paginated: false + + eval: + methods: + evaluate_rows: post /v1alpha/eval/benchmarks/{benchmark_id}/evaluations + run_eval: post /v1alpha/eval/benchmarks/{benchmark_id}/jobs + evaluate_rows_alpha: post /v1alpha/eval/benchmarks/{benchmark_id}/evaluations + run_eval_alpha: post /v1alpha/eval/benchmarks/{benchmark_id}/jobs + + subresources: + jobs: + methods: + cancel: delete /v1alpha/eval/benchmarks/{benchmark_id}/jobs/{job_id} + status: get /v1alpha/eval/benchmarks/{benchmark_id}/jobs/{job_id} + retrieve: get /v1alpha/eval/benchmarks/{benchmark_id}/jobs/{job_id}/result + models: + evaluate_response: EvaluateResponse + benchmark_config: BenchmarkConfig + job: Job + + agents: + methods: + create: post /v1alpha/agents + list: get /v1alpha/agents + retrieve: get /v1alpha/agents/{agent_id} + delete: delete /v1alpha/agents/{agent_id} + models: + inference_step: InferenceStep + tool_execution_step: ToolExecutionStep + tool_response: ToolResponse + shield_call_step: ShieldCallStep + memory_retrieval_step: MemoryRetrievalStep + subresources: + session: + models: + session: Session + methods: + list: get /v1alpha/agents/{agent_id}/sessions + create: post /v1alpha/agents/{agent_id}/session + delete: delete /v1alpha/agents/{agent_id}/session/{session_id} + retrieve: get /v1alpha/agents/{agent_id}/session/{session_id} + steps: + methods: + retrieve: get /v1alpha/agents/{agent_id}/session/{session_id}/turn/{turn_id}/step/{step_id} + turn: + models: + turn: Turn + turn_response_event: AgentTurnResponseEvent + agent_turn_response_stream_chunk: AgentTurnResponseStreamChunk + methods: + create: + type: http + endpoint: post /v1alpha/agents/{agent_id}/session/{session_id}/turn + streaming: + stream_event_model: alpha.agents.turn.agent_turn_response_stream_chunk + param_discriminator: stream + retrieve: get /v1alpha/agents/{agent_id}/session/{session_id}/turn/{turn_id} + resume: + type: http + endpoint: post /v1alpha/agents/{agent_id}/session/{session_id}/turn/{turn_id}/resume + streaming: + stream_event_model: alpha.agents.turn.agent_turn_response_stream_chunk + param_discriminator: stream + + beta: + subresources: + datasets: + models: + list_datasets_response: ListDatasetsResponse + methods: + register: post /v1beta/datasets + retrieve: get /v1beta/datasets/{dataset_id} + list: + endpoint: get /v1beta/datasets + paginated: false + unregister: delete /v1beta/datasets/{dataset_id} + iterrows: get /v1beta/datasetio/iterrows/{dataset_id} + appendrows: post /v1beta/datasetio/append-rows/{dataset_id} + + +settings: + license: MIT + unwrap_response_fields: [ data ] + +openapi: + transformations: + - command: renameValue + reason: pydantic reserved name + args: + filter: + only: + - '$.components.schemas.InferenceStep.properties.model_response' + rename: + python: + property_name: 'inference_model_response' + + # - command: renameValue + # reason: pydantic reserved name + # args: + # filter: + # only: + # - '$.components.schemas.Model.properties.model_type' + # rename: + # python: + # property_name: 'type' + - command: mergeObject + reason: Better return_type using enum + args: + target: + - '$.components.schemas' + object: + ReturnType: + additionalProperties: false + properties: + type: + enum: + - string + - number + - boolean + - array + - object + - json + - union + - chat_completion_input + - completion_input + - agent_turn_input + required: + - type + type: object + - command: replaceProperties + reason: Replace return type properties with better model (see above) + args: + filter: + only: + - '$.components.schemas.ScoringFn.properties.return_type' + - '$.components.schemas.RegisterScoringFunctionRequest.properties.return_type' + value: + $ref: '#/components/schemas/ReturnType' + - command: oneOfToAnyOf + reason: Prism (mock server) doesn't like one of our requests as it technically matches multiple variants + - reason: For better names + command: extractToRefs + args: + ref: + target: '$.components.schemas.ToolCallDelta.properties.tool_call' + name: '#/components/schemas/ToolCallOrString' + +# `readme` is used to configure the code snippets that will be rendered in the +# README.md of various SDKs. In particular, you can change the `headline` +# snippet's endpoint and the arguments to call it with. +readme: + example_requests: + default: + type: request + endpoint: post /v1/chat/completions + params: &ref_0 {} + headline: + type: request + endpoint: post /v1/models + params: *ref_0 + pagination: + type: request + endpoint: post /v1/chat/completions + params: {} diff --git a/client-sdks/stainless/openapi.yml b/client-sdks/stainless/openapi.yml new file mode 100644 index 000000000..93049a14a --- /dev/null +++ b/client-sdks/stainless/openapi.yml @@ -0,0 +1,13653 @@ +openapi: 3.1.0 +info: + title: >- + Llama Stack Specification - Stable & Experimental APIs + version: v1 + description: >- + This is the specification of the Llama Stack that provides + a set of endpoints and their corresponding interfaces that are + tailored to + best leverage Llama Models. + + **🔗 COMBINED**: This specification includes both stable production-ready APIs + and experimental pre-release APIs. Use stable APIs for production deployments + and experimental APIs for testing new features. +servers: + - url: http://any-hosted-llama-stack.com +paths: + /v1/chat/completions: + get: + responses: + '200': + description: A ListOpenAIChatCompletionResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ListOpenAIChatCompletionResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Inference + summary: List chat completions. + description: List chat completions. + parameters: + - name: after + in: query + description: >- + The ID of the last chat completion to return. + required: false + schema: + type: string + - name: limit + in: query + description: >- + The maximum number of chat completions to return. + required: false + schema: + type: integer + - name: model + in: query + description: The model to filter by. + required: false + schema: + type: string + - name: order + in: query + description: >- + The order to sort the chat completions by: "asc" or "desc". Defaults to + "desc". + required: false + schema: + $ref: '#/components/schemas/Order' + deprecated: false + post: + responses: + '200': + description: An OpenAIChatCompletion. + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/OpenAIChatCompletion' + - $ref: '#/components/schemas/OpenAIChatCompletionChunk' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Inference + summary: Create chat completions. + description: >- + Create chat completions. + + Generate an OpenAI-compatible chat completion for the given messages using + the specified model. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAIChatCompletionRequestWithExtraBody' + required: true + deprecated: false + /v1/chat/completions/{completion_id}: + get: + responses: + '200': + description: A OpenAICompletionWithInputMessages. + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAICompletionWithInputMessages' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Inference + summary: Get chat completion. + description: >- + Get chat completion. + + Describe a chat completion by its ID. + parameters: + - name: completion_id + in: path + description: ID of the chat completion. + required: true + schema: + type: string + deprecated: false + /v1/completions: + post: + responses: + '200': + description: An OpenAICompletion. + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAICompletion' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Inference + summary: Create completion. + description: >- + Create completion. + + Generate an OpenAI-compatible completion for the given prompt using the specified + model. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAICompletionRequestWithExtraBody' + required: true + deprecated: false + /v1/conversations: + post: + responses: + '200': + description: The created conversation object. + content: + application/json: + schema: + $ref: '#/components/schemas/Conversation' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Conversations + summary: Create a conversation. + description: >- + Create a conversation. + + Create a conversation. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateConversationRequest' + required: true + deprecated: false + /v1/conversations/{conversation_id}: + get: + responses: + '200': + description: The conversation object. + content: + application/json: + schema: + $ref: '#/components/schemas/Conversation' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Conversations + summary: Retrieve a conversation. + description: >- + Retrieve a conversation. + + Get a conversation with the given ID. + parameters: + - name: conversation_id + in: path + description: The conversation identifier. + required: true + schema: + type: string + deprecated: false + post: + responses: + '200': + description: The updated conversation object. + content: + application/json: + schema: + $ref: '#/components/schemas/Conversation' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Conversations + summary: Update a conversation. + description: >- + Update a conversation. + + Update a conversation's metadata with the given ID. + parameters: + - name: conversation_id + in: path + description: The conversation identifier. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdateConversationRequest' + required: true + deprecated: false + delete: + responses: + '200': + description: The deleted conversation resource. + content: + application/json: + schema: + $ref: '#/components/schemas/ConversationDeletedResource' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Conversations + summary: Delete a conversation. + description: >- + Delete a conversation. + + Delete a conversation with the given ID. + parameters: + - name: conversation_id + in: path + description: The conversation identifier. + required: true + schema: + type: string + deprecated: false + /v1/conversations/{conversation_id}/items: + get: + responses: + '200': + description: List of conversation items. + content: + application/json: + schema: + $ref: '#/components/schemas/ConversationItemList' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Conversations + summary: List items. + description: >- + List items. + + List items in the conversation. + parameters: + - name: conversation_id + in: path + description: The conversation identifier. + required: true + schema: + type: string + - name: after + in: query + description: >- + An item ID to list items after, used in pagination. + required: true + schema: + oneOf: + - type: string + - type: object + title: NotGiven + description: >- + A sentinel singleton class used to distinguish omitted keyword arguments + from those passed in with the value None (which may have different + behavior). + + For example: + + + ```py + + def get(timeout: Union[int, NotGiven, None] = NotGiven()) -> Response: + ... + + + + get(timeout=1) # 1s timeout + + get(timeout=None) # No timeout + + get() # Default timeout behavior, which may not be statically known + at the method definition. + + ``` + - name: include + in: query + description: >- + Specify additional output data to include in the response. + required: true + schema: + oneOf: + - type: array + items: + type: string + enum: + - code_interpreter_call.outputs + - computer_call_output.output.image_url + - file_search_call.results + - message.input_image.image_url + - message.output_text.logprobs + - reasoning.encrypted_content + - type: object + title: NotGiven + description: >- + A sentinel singleton class used to distinguish omitted keyword arguments + from those passed in with the value None (which may have different + behavior). + + For example: + + + ```py + + def get(timeout: Union[int, NotGiven, None] = NotGiven()) -> Response: + ... + + + + get(timeout=1) # 1s timeout + + get(timeout=None) # No timeout + + get() # Default timeout behavior, which may not be statically known + at the method definition. + + ``` + - name: limit + in: query + description: >- + A limit on the number of objects to be returned (1-100, default 20). + required: true + schema: + oneOf: + - type: integer + - type: object + title: NotGiven + description: >- + A sentinel singleton class used to distinguish omitted keyword arguments + from those passed in with the value None (which may have different + behavior). + + For example: + + + ```py + + def get(timeout: Union[int, NotGiven, None] = NotGiven()) -> Response: + ... + + + + get(timeout=1) # 1s timeout + + get(timeout=None) # No timeout + + get() # Default timeout behavior, which may not be statically known + at the method definition. + + ``` + - name: order + in: query + description: >- + The order to return items in (asc or desc, default desc). + required: true + schema: + oneOf: + - type: string + enum: + - asc + - desc + - type: object + title: NotGiven + description: >- + A sentinel singleton class used to distinguish omitted keyword arguments + from those passed in with the value None (which may have different + behavior). + + For example: + + + ```py + + def get(timeout: Union[int, NotGiven, None] = NotGiven()) -> Response: + ... + + + + get(timeout=1) # 1s timeout + + get(timeout=None) # No timeout + + get() # Default timeout behavior, which may not be statically known + at the method definition. + + ``` + deprecated: false + post: + responses: + '200': + description: List of created items. + content: + application/json: + schema: + $ref: '#/components/schemas/ConversationItemList' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Conversations + summary: Create items. + description: >- + Create items. + + Create items in the conversation. + parameters: + - name: conversation_id + in: path + description: The conversation identifier. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AddItemsRequest' + required: true + deprecated: false + /v1/conversations/{conversation_id}/items/{item_id}: + get: + responses: + '200': + description: The conversation item. + content: + application/json: + schema: + $ref: '#/components/schemas/ConversationItem' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Conversations + summary: Retrieve an item. + description: >- + Retrieve an item. + + Retrieve a conversation item. + parameters: + - name: conversation_id + in: path + description: The conversation identifier. + required: true + schema: + type: string + - name: item_id + in: path + description: The item identifier. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: The deleted item resource. + content: + application/json: + schema: + $ref: '#/components/schemas/ConversationItemDeletedResource' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Conversations + summary: Delete an item. + description: >- + Delete an item. + + Delete a conversation item. + parameters: + - name: conversation_id + in: path + description: The conversation identifier. + required: true + schema: + type: string + - name: item_id + in: path + description: The item identifier. + required: true + schema: + type: string + deprecated: false + /v1/embeddings: + post: + responses: + '200': + description: >- + An OpenAIEmbeddingsResponse containing the embeddings. + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAIEmbeddingsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Inference + summary: Create embeddings. + description: >- + Create embeddings. + + Generate OpenAI-compatible embeddings for the given input using the specified + model. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAIEmbeddingsRequestWithExtraBody' + required: true + deprecated: false + /v1/files: + get: + responses: + '200': + description: >- + An ListOpenAIFileResponse containing the list of files. + content: + application/json: + schema: + $ref: '#/components/schemas/ListOpenAIFileResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Files + summary: List files. + description: >- + List files. + + Returns a list of files that belong to the user's organization. + parameters: + - name: after + in: query + description: >- + A cursor for use in pagination. `after` is an object ID that defines your + place in the list. For instance, if you make a list request and receive + 100 objects, ending with obj_foo, your subsequent call can include after=obj_foo + in order to fetch the next page of the list. + required: false + schema: + type: string + - name: limit + in: query + description: >- + A limit on the number of objects to be returned. Limit can range between + 1 and 10,000, and the default is 10,000. + required: false + schema: + type: integer + - name: order + in: query + description: >- + Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + required: false + schema: + $ref: '#/components/schemas/Order' + - name: purpose + in: query + description: >- + Only return files with the given purpose. + required: false + schema: + $ref: '#/components/schemas/OpenAIFilePurpose' + deprecated: false + post: + responses: + '200': + description: >- + An OpenAIFileObject representing the uploaded file. + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAIFileObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Files + summary: Upload file. + description: >- + Upload file. + + Upload a file that can be used across various endpoints. + + + The file upload should be a multipart form request with: + + - file: The File object (not file name) to be uploaded. + + - purpose: The intended purpose of the uploaded file. + + - expires_after: Optional form values describing expiration for the file. + parameters: [] + requestBody: + content: + multipart/form-data: + schema: + type: object + properties: + file: + type: string + format: binary + purpose: + $ref: '#/components/schemas/OpenAIFilePurpose' + expires_after: + $ref: '#/components/schemas/ExpiresAfter' + required: + - file + - purpose + required: true + deprecated: false + /v1/files/{file_id}: + get: + responses: + '200': + description: >- + An OpenAIFileObject containing file information. + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAIFileObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Files + summary: Retrieve file. + description: >- + Retrieve file. + + Returns information about a specific file. + parameters: + - name: file_id + in: path + description: >- + The ID of the file to use for this request. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: >- + An OpenAIFileDeleteResponse indicating successful deletion. + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAIFileDeleteResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Files + summary: Delete file. + description: Delete file. + parameters: + - name: file_id + in: path + description: >- + The ID of the file to use for this request. + required: true + schema: + type: string + deprecated: false + /v1/files/{file_id}/content: + get: + responses: + '200': + description: >- + The raw file content as a binary response. + content: + application/json: + schema: + $ref: '#/components/schemas/Response' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Files + summary: Retrieve file content. + description: >- + Retrieve file content. + + Returns the contents of the specified file. + parameters: + - name: file_id + in: path + description: >- + The ID of the file to use for this request. + required: true + schema: + type: string + deprecated: false + /v1/health: + get: + responses: + '200': + description: >- + Health information indicating if the service is operational. + content: + application/json: + schema: + $ref: '#/components/schemas/HealthInfo' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Inspect + summary: Get health status. + description: >- + Get health status. + + Get the current health status of the service. + parameters: [] + deprecated: false + /v1/inspect/routes: + get: + responses: + '200': + description: >- + Response containing information about all available routes. + content: + application/json: + schema: + $ref: '#/components/schemas/ListRoutesResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Inspect + summary: List routes. + description: >- + List routes. + + List all available API routes with their methods and implementing providers. + parameters: [] + deprecated: false + /v1/models: + get: + responses: + '200': + description: A ListModelsResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ListModelsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Models + summary: List all models. + description: List all models. + parameters: [] + deprecated: false + post: + responses: + '200': + description: A Model. + content: + application/json: + schema: + $ref: '#/components/schemas/Model' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Models + summary: Register model. + description: >- + Register model. + + Register a model. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegisterModelRequest' + required: true + deprecated: false + /v1/models/{model_id}: + get: + responses: + '200': + description: A Model. + content: + application/json: + schema: + $ref: '#/components/schemas/Model' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Models + summary: Get model. + description: >- + Get model. + + Get a model by its identifier. + parameters: + - name: model_id + in: path + description: The identifier of the model to get. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Models + summary: Unregister model. + description: >- + Unregister model. + + Unregister a model. + parameters: + - name: model_id + in: path + description: >- + The identifier of the model to unregister. + required: true + schema: + type: string + deprecated: false + /v1/moderations: + post: + responses: + '200': + description: A moderation object. + content: + application/json: + schema: + $ref: '#/components/schemas/ModerationObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Safety + summary: Create moderation. + description: >- + Create moderation. + + Classifies if text and/or image inputs are potentially harmful. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RunModerationRequest' + required: true + deprecated: false + /v1/prompts: + get: + responses: + '200': + description: >- + A ListPromptsResponse containing all prompts. + content: + application/json: + schema: + $ref: '#/components/schemas/ListPromptsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Prompts + summary: List all prompts. + description: List all prompts. + parameters: [] + deprecated: false + post: + responses: + '200': + description: The created Prompt resource. + content: + application/json: + schema: + $ref: '#/components/schemas/Prompt' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Prompts + summary: Create prompt. + description: >- + Create prompt. + + Create a new prompt. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreatePromptRequest' + required: true + deprecated: false + /v1/prompts/{prompt_id}: + get: + responses: + '200': + description: A Prompt resource. + content: + application/json: + schema: + $ref: '#/components/schemas/Prompt' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Prompts + summary: Get prompt. + description: >- + Get prompt. + + Get a prompt by its identifier and optional version. + parameters: + - name: prompt_id + in: path + description: The identifier of the prompt to get. + required: true + schema: + type: string + - name: version + in: query + description: >- + The version of the prompt to get (defaults to latest). + required: false + schema: + type: integer + deprecated: false + post: + responses: + '200': + description: >- + The updated Prompt resource with incremented version. + content: + application/json: + schema: + $ref: '#/components/schemas/Prompt' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Prompts + summary: Update prompt. + description: >- + Update prompt. + + Update an existing prompt (increments version). + parameters: + - name: prompt_id + in: path + description: The identifier of the prompt to update. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/UpdatePromptRequest' + required: true + deprecated: false + delete: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Prompts + summary: Delete prompt. + description: >- + Delete prompt. + + Delete a prompt. + parameters: + - name: prompt_id + in: path + description: The identifier of the prompt to delete. + required: true + schema: + type: string + deprecated: false + /v1/prompts/{prompt_id}/set-default-version: + post: + responses: + '200': + description: >- + The prompt with the specified version now set as default. + content: + application/json: + schema: + $ref: '#/components/schemas/Prompt' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Prompts + summary: Set prompt version. + description: >- + Set prompt version. + + Set which version of a prompt should be the default in get_prompt (latest). + parameters: + - name: prompt_id + in: path + description: The identifier of the prompt. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SetDefaultVersionRequest' + required: true + deprecated: false + /v1/prompts/{prompt_id}/versions: + get: + responses: + '200': + description: >- + A ListPromptsResponse containing all versions of the prompt. + content: + application/json: + schema: + $ref: '#/components/schemas/ListPromptsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Prompts + summary: List prompt versions. + description: >- + List prompt versions. + + List all versions of a specific prompt. + parameters: + - name: prompt_id + in: path + description: >- + The identifier of the prompt to list versions for. + required: true + schema: + type: string + deprecated: false + /v1/providers: + get: + responses: + '200': + description: >- + A ListProvidersResponse containing information about all providers. + content: + application/json: + schema: + $ref: '#/components/schemas/ListProvidersResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Providers + summary: List providers. + description: >- + List providers. + + List all available providers. + parameters: [] + deprecated: false + /v1/providers/{provider_id}: + get: + responses: + '200': + description: >- + A ProviderInfo object containing the provider's details. + content: + application/json: + schema: + $ref: '#/components/schemas/ProviderInfo' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Providers + summary: Get provider. + description: >- + Get provider. + + Get detailed information about a specific provider. + parameters: + - name: provider_id + in: path + description: The ID of the provider to inspect. + required: true + schema: + type: string + deprecated: false + /v1/responses: + get: + responses: + '200': + description: A ListOpenAIResponseObject. + content: + application/json: + schema: + $ref: '#/components/schemas/ListOpenAIResponseObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: List all responses. + description: List all responses. + parameters: + - name: after + in: query + description: The ID of the last response to return. + required: false + schema: + type: string + - name: limit + in: query + description: The number of responses to return. + required: false + schema: + type: integer + - name: model + in: query + description: The model to filter responses by. + required: false + schema: + type: string + - name: order + in: query + description: >- + The order to sort responses by when sorted by created_at ('asc' or 'desc'). + required: false + schema: + $ref: '#/components/schemas/Order' + deprecated: false + post: + responses: + '200': + description: An OpenAIResponseObject. + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAIResponseObject' + text/event-stream: + schema: + $ref: '#/components/schemas/OpenAIResponseObjectStream' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: Create a model response. + description: Create a model response. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateOpenaiResponseRequest' + required: true + deprecated: false + x-llama-stack-extra-body-params: + - name: guardrails + schema: + type: array + items: + oneOf: + - type: string + - $ref: '#/components/schemas/ResponseGuardrailSpec' + description: >- + List of guardrails to apply during response generation. Guardrails provide + safety and content moderation. + required: false + /v1/responses/{response_id}: + get: + responses: + '200': + description: An OpenAIResponseObject. + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAIResponseObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: Get a model response. + description: Get a model response. + parameters: + - name: response_id + in: path + description: >- + The ID of the OpenAI response to retrieve. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: An OpenAIDeleteResponseObject + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAIDeleteResponseObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: Delete a response. + description: Delete a response. + parameters: + - name: response_id + in: path + description: The ID of the OpenAI response to delete. + required: true + schema: + type: string + deprecated: false + /v1/responses/{response_id}/input_items: + get: + responses: + '200': + description: An ListOpenAIResponseInputItem. + content: + application/json: + schema: + $ref: '#/components/schemas/ListOpenAIResponseInputItem' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: List input items. + description: List input items. + parameters: + - name: response_id + in: path + description: >- + The ID of the response to retrieve input items for. + required: true + schema: + type: string + - name: after + in: query + description: >- + An item ID to list items after, used for pagination. + required: false + schema: + type: string + - name: before + in: query + description: >- + An item ID to list items before, used for pagination. + required: false + schema: + type: string + - name: include + in: query + description: >- + Additional fields to include in the response. + required: false + schema: + type: array + items: + type: string + - name: limit + in: query + description: >- + A limit on the number of objects to be returned. Limit can range between + 1 and 100, and the default is 20. + required: false + schema: + type: integer + - name: order + in: query + description: >- + The order to return the input items in. Default is desc. + required: false + schema: + $ref: '#/components/schemas/Order' + deprecated: false + /v1/safety/run-shield: + post: + responses: + '200': + description: A RunShieldResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/RunShieldResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Safety + summary: Run shield. + description: >- + Run shield. + + Run a shield. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RunShieldRequest' + required: true + deprecated: false + /v1/scoring-functions: + get: + responses: + '200': + description: A ListScoringFunctionsResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ListScoringFunctionsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ScoringFunctions + summary: List all scoring functions. + description: List all scoring functions. + parameters: [] + deprecated: false + post: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ScoringFunctions + summary: Register a scoring function. + description: Register a scoring function. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegisterScoringFunctionRequest' + required: true + deprecated: false + /v1/scoring-functions/{scoring_fn_id}: + get: + responses: + '200': + description: A ScoringFn. + content: + application/json: + schema: + $ref: '#/components/schemas/ScoringFn' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ScoringFunctions + summary: Get a scoring function by its ID. + description: Get a scoring function by its ID. + parameters: + - name: scoring_fn_id + in: path + description: The ID of the scoring function to get. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ScoringFunctions + summary: Unregister a scoring function. + description: Unregister a scoring function. + parameters: + - name: scoring_fn_id + in: path + description: >- + The ID of the scoring function to unregister. + required: true + schema: + type: string + deprecated: false + /v1/scoring/score: + post: + responses: + '200': + description: >- + A ScoreResponse object containing rows and aggregated results. + content: + application/json: + schema: + $ref: '#/components/schemas/ScoreResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Scoring + summary: Score a list of rows. + description: Score a list of rows. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ScoreRequest' + required: true + deprecated: false + /v1/scoring/score-batch: + post: + responses: + '200': + description: A ScoreBatchResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ScoreBatchResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Scoring + summary: Score a batch of rows. + description: Score a batch of rows. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ScoreBatchRequest' + required: true + deprecated: false + /v1/shields: + get: + responses: + '200': + description: A ListShieldsResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ListShieldsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Shields + summary: List all shields. + description: List all shields. + parameters: [] + deprecated: false + post: + responses: + '200': + description: A Shield. + content: + application/json: + schema: + $ref: '#/components/schemas/Shield' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Shields + summary: Register a shield. + description: Register a shield. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegisterShieldRequest' + required: true + deprecated: false + /v1/shields/{identifier}: + get: + responses: + '200': + description: A Shield. + content: + application/json: + schema: + $ref: '#/components/schemas/Shield' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Shields + summary: Get a shield by its identifier. + description: Get a shield by its identifier. + parameters: + - name: identifier + in: path + description: The identifier of the shield to get. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Shields + summary: Unregister a shield. + description: Unregister a shield. + parameters: + - name: identifier + in: path + description: >- + The identifier of the shield to unregister. + required: true + schema: + type: string + deprecated: false + /v1/synthetic-data-generation/generate: + post: + responses: + '200': + description: >- + Response containing filtered synthetic data samples and optional statistics + content: + application/json: + schema: + $ref: '#/components/schemas/SyntheticDataGenerationResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - SyntheticDataGeneration (Coming Soon) + summary: >- + Generate synthetic data based on input dialogs and apply filtering. + description: >- + Generate synthetic data based on input dialogs and apply filtering. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SyntheticDataGenerateRequest' + required: true + deprecated: false + /v1/tool-runtime/invoke: + post: + responses: + '200': + description: A ToolInvocationResult. + content: + application/json: + schema: + $ref: '#/components/schemas/ToolInvocationResult' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ToolRuntime + summary: Run a tool with the given arguments. + description: Run a tool with the given arguments. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/InvokeToolRequest' + required: true + deprecated: false + /v1/tool-runtime/list-tools: + get: + responses: + '200': + description: A ListToolDefsResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ListToolDefsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ToolRuntime + summary: List all tools in the runtime. + description: List all tools in the runtime. + parameters: + - name: tool_group_id + in: query + description: >- + The ID of the tool group to list tools for. + required: false + schema: + type: string + - name: mcp_endpoint + in: query + description: >- + The MCP endpoint to use for the tool group. + required: false + schema: + $ref: '#/components/schemas/URL' + deprecated: false + /v1/tool-runtime/rag-tool/insert: + post: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ToolRuntime + summary: >- + Index documents so they can be used by the RAG system. + description: >- + Index documents so they can be used by the RAG system. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/InsertRequest' + required: true + deprecated: false + /v1/tool-runtime/rag-tool/query: + post: + responses: + '200': + description: >- + RAGQueryResult containing the retrieved content and metadata + content: + application/json: + schema: + $ref: '#/components/schemas/RAGQueryResult' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ToolRuntime + summary: >- + Query the RAG system for context; typically invoked by the agent. + description: >- + Query the RAG system for context; typically invoked by the agent. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/QueryRequest' + required: true + deprecated: false + /v1/toolgroups: + get: + responses: + '200': + description: A ListToolGroupsResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ListToolGroupsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ToolGroups + summary: List tool groups with optional provider. + description: List tool groups with optional provider. + parameters: [] + deprecated: false + post: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ToolGroups + summary: Register a tool group. + description: Register a tool group. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegisterToolGroupRequest' + required: true + deprecated: false + /v1/toolgroups/{toolgroup_id}: + get: + responses: + '200': + description: A ToolGroup. + content: + application/json: + schema: + $ref: '#/components/schemas/ToolGroup' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ToolGroups + summary: Get a tool group by its ID. + description: Get a tool group by its ID. + parameters: + - name: toolgroup_id + in: path + description: The ID of the tool group to get. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ToolGroups + summary: Unregister a tool group. + description: Unregister a tool group. + parameters: + - name: toolgroup_id + in: path + description: The ID of the tool group to unregister. + required: true + schema: + type: string + deprecated: false + /v1/tools: + get: + responses: + '200': + description: A ListToolDefsResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ListToolDefsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ToolGroups + summary: List tools with optional tool group. + description: List tools with optional tool group. + parameters: + - name: toolgroup_id + in: query + description: >- + The ID of the tool group to list tools for. + required: false + schema: + type: string + deprecated: false + /v1/tools/{tool_name}: + get: + responses: + '200': + description: A ToolDef. + content: + application/json: + schema: + $ref: '#/components/schemas/ToolDef' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - ToolGroups + summary: Get a tool by its name. + description: Get a tool by its name. + parameters: + - name: tool_name + in: path + description: The name of the tool to get. + required: true + schema: + type: string + deprecated: false + /v1/vector-io/insert: + post: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Insert chunks into a vector database. + description: Insert chunks into a vector database. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/InsertChunksRequest' + required: true + deprecated: false + /v1/vector-io/query: + post: + responses: + '200': + description: A QueryChunksResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/QueryChunksResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Query chunks from a vector database. + description: Query chunks from a vector database. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/QueryChunksRequest' + required: true + deprecated: false + /v1/vector_stores: + get: + responses: + '200': + description: >- + A VectorStoreListResponse containing the list of vector stores. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreListResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Returns a list of vector stores. + description: Returns a list of vector stores. + parameters: + - name: limit + in: query + description: >- + A limit on the number of objects to be returned. Limit can range between + 1 and 100, and the default is 20. + required: false + schema: + type: integer + - name: order + in: query + description: >- + Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + required: false + schema: + type: string + - name: after + in: query + description: >- + A cursor for use in pagination. `after` is an object ID that defines your + place in the list. + required: false + schema: + type: string + - name: before + in: query + description: >- + A cursor for use in pagination. `before` is an object ID that defines + your place in the list. + required: false + schema: + type: string + deprecated: false + post: + responses: + '200': + description: >- + A VectorStoreObject representing the created vector store. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Creates a vector store. + description: >- + Creates a vector store. + + Generate an OpenAI-compatible vector store with the given parameters. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAICreateVectorStoreRequestWithExtraBody' + required: true + deprecated: false + /v1/vector_stores/{vector_store_id}: + get: + responses: + '200': + description: >- + A VectorStoreObject representing the vector store. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Retrieves a vector store. + description: Retrieves a vector store. + parameters: + - name: vector_store_id + in: path + description: The ID of the vector store to retrieve. + required: true + schema: + type: string + deprecated: false + post: + responses: + '200': + description: >- + A VectorStoreObject representing the updated vector store. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Updates a vector store. + description: Updates a vector store. + parameters: + - name: vector_store_id + in: path + description: The ID of the vector store to update. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OpenaiUpdateVectorStoreRequest' + required: true + deprecated: false + delete: + responses: + '200': + description: >- + A VectorStoreDeleteResponse indicating the deletion status. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreDeleteResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Delete a vector store. + description: Delete a vector store. + parameters: + - name: vector_store_id + in: path + description: The ID of the vector store to delete. + required: true + schema: + type: string + deprecated: false + /v1/vector_stores/{vector_store_id}/file_batches: + post: + responses: + '200': + description: >- + A VectorStoreFileBatchObject representing the created file batch. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreFileBatchObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Create a vector store file batch. + description: >- + Create a vector store file batch. + + Generate an OpenAI-compatible vector store file batch for the given vector + store. + parameters: + - name: vector_store_id + in: path + description: >- + The ID of the vector store to create the file batch for. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OpenAICreateVectorStoreFileBatchRequestWithExtraBody' + required: true + deprecated: false + /v1/vector_stores/{vector_store_id}/file_batches/{batch_id}: + get: + responses: + '200': + description: >- + A VectorStoreFileBatchObject representing the file batch. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreFileBatchObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Retrieve a vector store file batch. + description: Retrieve a vector store file batch. + parameters: + - name: batch_id + in: path + description: The ID of the file batch to retrieve. + required: true + schema: + type: string + - name: vector_store_id + in: path + description: >- + The ID of the vector store containing the file batch. + required: true + schema: + type: string + deprecated: false + /v1/vector_stores/{vector_store_id}/file_batches/{batch_id}/cancel: + post: + responses: + '200': + description: >- + A VectorStoreFileBatchObject representing the cancelled file batch. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreFileBatchObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Cancels a vector store file batch. + description: Cancels a vector store file batch. + parameters: + - name: batch_id + in: path + description: The ID of the file batch to cancel. + required: true + schema: + type: string + - name: vector_store_id + in: path + description: >- + The ID of the vector store containing the file batch. + required: true + schema: + type: string + deprecated: false + /v1/vector_stores/{vector_store_id}/file_batches/{batch_id}/files: + get: + responses: + '200': + description: >- + A VectorStoreFilesListInBatchResponse containing the list of files in + the batch. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreFilesListInBatchResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: >- + Returns a list of vector store files in a batch. + description: >- + Returns a list of vector store files in a batch. + parameters: + - name: batch_id + in: path + description: >- + The ID of the file batch to list files from. + required: true + schema: + type: string + - name: vector_store_id + in: path + description: >- + The ID of the vector store containing the file batch. + required: true + schema: + type: string + - name: after + in: query + description: >- + A cursor for use in pagination. `after` is an object ID that defines your + place in the list. + required: false + schema: + type: string + - name: before + in: query + description: >- + A cursor for use in pagination. `before` is an object ID that defines + your place in the list. + required: false + schema: + type: string + - name: filter + in: query + description: >- + Filter by file status. One of in_progress, completed, failed, cancelled. + required: false + schema: + type: string + - name: limit + in: query + description: >- + A limit on the number of objects to be returned. Limit can range between + 1 and 100, and the default is 20. + required: false + schema: + type: integer + - name: order + in: query + description: >- + Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + required: false + schema: + type: string + deprecated: false + /v1/vector_stores/{vector_store_id}/files: + get: + responses: + '200': + description: >- + A VectorStoreListFilesResponse containing the list of files. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreListFilesResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: List files in a vector store. + description: List files in a vector store. + parameters: + - name: vector_store_id + in: path + description: >- + The ID of the vector store to list files from. + required: true + schema: + type: string + - name: limit + in: query + description: >- + (Optional) A limit on the number of objects to be returned. Limit can + range between 1 and 100, and the default is 20. + required: false + schema: + type: integer + - name: order + in: query + description: >- + (Optional) Sort order by the `created_at` timestamp of the objects. `asc` + for ascending order and `desc` for descending order. + required: false + schema: + type: string + - name: after + in: query + description: >- + (Optional) A cursor for use in pagination. `after` is an object ID that + defines your place in the list. + required: false + schema: + type: string + - name: before + in: query + description: >- + (Optional) A cursor for use in pagination. `before` is an object ID that + defines your place in the list. + required: false + schema: + type: string + - name: filter + in: query + description: >- + (Optional) Filter by file status to only return files with the specified + status. + required: false + schema: + $ref: '#/components/schemas/VectorStoreFileStatus' + deprecated: false + post: + responses: + '200': + description: >- + A VectorStoreFileObject representing the attached file. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreFileObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Attach a file to a vector store. + description: Attach a file to a vector store. + parameters: + - name: vector_store_id + in: path + description: >- + The ID of the vector store to attach the file to. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OpenaiAttachFileToVectorStoreRequest' + required: true + deprecated: false + /v1/vector_stores/{vector_store_id}/files/{file_id}: + get: + responses: + '200': + description: >- + A VectorStoreFileObject representing the file. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreFileObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Retrieves a vector store file. + description: Retrieves a vector store file. + parameters: + - name: vector_store_id + in: path + description: >- + The ID of the vector store containing the file to retrieve. + required: true + schema: + type: string + - name: file_id + in: path + description: The ID of the file to retrieve. + required: true + schema: + type: string + deprecated: false + post: + responses: + '200': + description: >- + A VectorStoreFileObject representing the updated file. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreFileObject' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Updates a vector store file. + description: Updates a vector store file. + parameters: + - name: vector_store_id + in: path + description: >- + The ID of the vector store containing the file to update. + required: true + schema: + type: string + - name: file_id + in: path + description: The ID of the file to update. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OpenaiUpdateVectorStoreFileRequest' + required: true + deprecated: false + delete: + responses: + '200': + description: >- + A VectorStoreFileDeleteResponse indicating the deletion status. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreFileDeleteResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Delete a vector store file. + description: Delete a vector store file. + parameters: + - name: vector_store_id + in: path + description: >- + The ID of the vector store containing the file to delete. + required: true + schema: + type: string + - name: file_id + in: path + description: The ID of the file to delete. + required: true + schema: + type: string + deprecated: false + /v1/vector_stores/{vector_store_id}/files/{file_id}/content: + get: + responses: + '200': + description: >- + A list of InterleavedContent representing the file contents. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreFileContentsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: >- + Retrieves the contents of a vector store file. + description: >- + Retrieves the contents of a vector store file. + parameters: + - name: vector_store_id + in: path + description: >- + The ID of the vector store containing the file to retrieve. + required: true + schema: + type: string + - name: file_id + in: path + description: The ID of the file to retrieve. + required: true + schema: + type: string + deprecated: false + /v1/vector_stores/{vector_store_id}/search: + post: + responses: + '200': + description: >- + A VectorStoreSearchResponse containing the search results. + content: + application/json: + schema: + $ref: '#/components/schemas/VectorStoreSearchResponsePage' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - VectorIO + summary: Search for chunks in a vector store. + description: >- + Search for chunks in a vector store. + + Searches a vector store for relevant chunks based on a query and optional + file attribute filters. + parameters: + - name: vector_store_id + in: path + description: The ID of the vector store to search. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/OpenaiSearchVectorStoreRequest' + required: true + deprecated: false + /v1/version: + get: + responses: + '200': + description: >- + Version information containing the service version number. + content: + application/json: + schema: + $ref: '#/components/schemas/VersionInfo' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Inspect + summary: Get version. + description: >- + Get version. + + Get the version of the service. + parameters: [] + deprecated: false + /v1beta/datasetio/append-rows/{dataset_id}: + post: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - DatasetIO + summary: Append rows to a dataset. + description: Append rows to a dataset. + parameters: + - name: dataset_id + in: path + description: >- + The ID of the dataset to append the rows to. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/AppendRowsRequest' + required: true + deprecated: false + /v1beta/datasetio/iterrows/{dataset_id}: + get: + responses: + '200': + description: A PaginatedResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/PaginatedResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - DatasetIO + summary: >- + Get a paginated list of rows from a dataset. + description: >- + Get a paginated list of rows from a dataset. + + Uses offset-based pagination where: + + - start_index: The starting index (0-based). If None, starts from beginning. + + - limit: Number of items to return. If None or -1, returns all items. + + + The response includes: + + - data: List of items for the current page. + + - has_more: Whether there are more items available after this set. + parameters: + - name: dataset_id + in: path + description: >- + The ID of the dataset to get the rows from. + required: true + schema: + type: string + - name: start_index + in: query + description: >- + Index into dataset for the first row to get. Get all rows if None. + required: false + schema: + type: integer + - name: limit + in: query + description: The number of rows to get. + required: false + schema: + type: integer + deprecated: false + /v1beta/datasets: + get: + responses: + '200': + description: A ListDatasetsResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ListDatasetsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Datasets + summary: List all datasets. + description: List all datasets. + parameters: [] + deprecated: false + post: + responses: + '200': + description: A Dataset. + content: + application/json: + schema: + $ref: '#/components/schemas/Dataset' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Datasets + summary: Register a new dataset. + description: Register a new dataset. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegisterDatasetRequest' + required: true + deprecated: false + /v1beta/datasets/{dataset_id}: + get: + responses: + '200': + description: A Dataset. + content: + application/json: + schema: + $ref: '#/components/schemas/Dataset' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Datasets + summary: Get a dataset by its ID. + description: Get a dataset by its ID. + parameters: + - name: dataset_id + in: path + description: The ID of the dataset to get. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Datasets + summary: Unregister a dataset by its ID. + description: Unregister a dataset by its ID. + parameters: + - name: dataset_id + in: path + description: The ID of the dataset to unregister. + required: true + schema: + type: string + deprecated: false + /v1alpha/agents: + get: + responses: + '200': + description: A PaginatedResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/PaginatedResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: List all agents. + description: List all agents. + parameters: + - name: start_index + in: query + description: The index to start the pagination from. + required: false + schema: + type: integer + - name: limit + in: query + description: The number of agents to return. + required: false + schema: + type: integer + deprecated: false + post: + responses: + '200': + description: >- + An AgentCreateResponse with the agent ID. + content: + application/json: + schema: + $ref: '#/components/schemas/AgentCreateResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: >- + Create an agent with the given configuration. + description: >- + Create an agent with the given configuration. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAgentRequest' + required: true + deprecated: false + /v1alpha/agents/{agent_id}: + get: + responses: + '200': + description: An Agent of the agent. + content: + application/json: + schema: + $ref: '#/components/schemas/Agent' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: Describe an agent by its ID. + description: Describe an agent by its ID. + parameters: + - name: agent_id + in: path + description: ID of the agent. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: >- + Delete an agent by its ID and its associated sessions and turns. + description: >- + Delete an agent by its ID and its associated sessions and turns. + parameters: + - name: agent_id + in: path + description: The ID of the agent to delete. + required: true + schema: + type: string + deprecated: false + /v1alpha/agents/{agent_id}/session: + post: + responses: + '200': + description: An AgentSessionCreateResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/AgentSessionCreateResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: Create a new session for an agent. + description: Create a new session for an agent. + parameters: + - name: agent_id + in: path + description: >- + The ID of the agent to create the session for. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAgentSessionRequest' + required: true + deprecated: false + /v1alpha/agents/{agent_id}/session/{session_id}: + get: + responses: + '200': + description: A Session. + content: + application/json: + schema: + $ref: '#/components/schemas/Session' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: Retrieve an agent session by its ID. + description: Retrieve an agent session by its ID. + parameters: + - name: session_id + in: path + description: The ID of the session to get. + required: true + schema: + type: string + - name: agent_id + in: path + description: >- + The ID of the agent to get the session for. + required: true + schema: + type: string + - name: turn_ids + in: query + description: >- + (Optional) List of turn IDs to filter the session by. + required: false + schema: + type: array + items: + type: string + deprecated: false + delete: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: >- + Delete an agent session by its ID and its associated turns. + description: >- + Delete an agent session by its ID and its associated turns. + parameters: + - name: session_id + in: path + description: The ID of the session to delete. + required: true + schema: + type: string + - name: agent_id + in: path + description: >- + The ID of the agent to delete the session for. + required: true + schema: + type: string + deprecated: false + /v1alpha/agents/{agent_id}/session/{session_id}/turn: + post: + responses: + '200': + description: >- + If stream=False, returns a Turn object. If stream=True, returns an SSE + event stream of AgentTurnResponseStreamChunk. + content: + application/json: + schema: + $ref: '#/components/schemas/Turn' + text/event-stream: + schema: + $ref: '#/components/schemas/AgentTurnResponseStreamChunk' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: Create a new turn for an agent. + description: Create a new turn for an agent. + parameters: + - name: agent_id + in: path + description: >- + The ID of the agent to create the turn for. + required: true + schema: + type: string + - name: session_id + in: path + description: >- + The ID of the session to create the turn for. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CreateAgentTurnRequest' + required: true + deprecated: false + /v1alpha/agents/{agent_id}/session/{session_id}/turn/{turn_id}: + get: + responses: + '200': + description: A Turn. + content: + application/json: + schema: + $ref: '#/components/schemas/Turn' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: Retrieve an agent turn by its ID. + description: Retrieve an agent turn by its ID. + parameters: + - name: agent_id + in: path + description: The ID of the agent to get the turn for. + required: true + schema: + type: string + - name: session_id + in: path + description: >- + The ID of the session to get the turn for. + required: true + schema: + type: string + - name: turn_id + in: path + description: The ID of the turn to get. + required: true + schema: + type: string + deprecated: false + /v1alpha/agents/{agent_id}/session/{session_id}/turn/{turn_id}/resume: + post: + responses: + '200': + description: >- + A Turn object if stream is False, otherwise an AsyncIterator of AgentTurnResponseStreamChunk + objects. + content: + application/json: + schema: + $ref: '#/components/schemas/Turn' + text/event-stream: + schema: + $ref: '#/components/schemas/AgentTurnResponseStreamChunk' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: >- + Resume an agent turn with executed tool call responses. + description: >- + Resume an agent turn with executed tool call responses. + + When a Turn has the status `awaiting_input` due to pending input from client + side tool calls, this endpoint can be used to submit the outputs from the + tool calls once they are ready. + parameters: + - name: agent_id + in: path + description: The ID of the agent to resume. + required: true + schema: + type: string + - name: session_id + in: path + description: The ID of the session to resume. + required: true + schema: + type: string + - name: turn_id + in: path + description: The ID of the turn to resume. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/ResumeAgentTurnRequest' + required: true + deprecated: false + /v1alpha/agents/{agent_id}/session/{session_id}/turn/{turn_id}/step/{step_id}: + get: + responses: + '200': + description: An AgentStepResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/AgentStepResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: Retrieve an agent step by its ID. + description: Retrieve an agent step by its ID. + parameters: + - name: agent_id + in: path + description: The ID of the agent to get the step for. + required: true + schema: + type: string + - name: session_id + in: path + description: >- + The ID of the session to get the step for. + required: true + schema: + type: string + - name: turn_id + in: path + description: The ID of the turn to get the step for. + required: true + schema: + type: string + - name: step_id + in: path + description: The ID of the step to get. + required: true + schema: + type: string + deprecated: false + /v1alpha/agents/{agent_id}/sessions: + get: + responses: + '200': + description: A PaginatedResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/PaginatedResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Agents + summary: List all session(s) of a given agent. + description: List all session(s) of a given agent. + parameters: + - name: agent_id + in: path + description: >- + The ID of the agent to list sessions for. + required: true + schema: + type: string + - name: start_index + in: query + description: The index to start the pagination from. + required: false + schema: + type: integer + - name: limit + in: query + description: The number of sessions to return. + required: false + schema: + type: integer + deprecated: false + /v1alpha/eval/benchmarks: + get: + responses: + '200': + description: A ListBenchmarksResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ListBenchmarksResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Benchmarks + summary: List all benchmarks. + description: List all benchmarks. + parameters: [] + deprecated: false + post: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Benchmarks + summary: Register a benchmark. + description: Register a benchmark. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RegisterBenchmarkRequest' + required: true + deprecated: false + /v1alpha/eval/benchmarks/{benchmark_id}: + get: + responses: + '200': + description: A Benchmark. + content: + application/json: + schema: + $ref: '#/components/schemas/Benchmark' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Benchmarks + summary: Get a benchmark by its ID. + description: Get a benchmark by its ID. + parameters: + - name: benchmark_id + in: path + description: The ID of the benchmark to get. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Benchmarks + summary: Unregister a benchmark. + description: Unregister a benchmark. + parameters: + - name: benchmark_id + in: path + description: The ID of the benchmark to unregister. + required: true + schema: + type: string + deprecated: false + /v1alpha/eval/benchmarks/{benchmark_id}/evaluations: + post: + responses: + '200': + description: >- + EvaluateResponse object containing generations and scores. + content: + application/json: + schema: + $ref: '#/components/schemas/EvaluateResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Eval + summary: Evaluate a list of rows on a benchmark. + description: Evaluate a list of rows on a benchmark. + parameters: + - name: benchmark_id + in: path + description: >- + The ID of the benchmark to run the evaluation on. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/EvaluateRowsRequest' + required: true + deprecated: false + /v1alpha/eval/benchmarks/{benchmark_id}/jobs: + post: + responses: + '200': + description: >- + The job that was created to run the evaluation. + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Eval + summary: Run an evaluation on a benchmark. + description: Run an evaluation on a benchmark. + parameters: + - name: benchmark_id + in: path + description: >- + The ID of the benchmark to run the evaluation on. + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RunEvalRequest' + required: true + deprecated: false + /v1alpha/eval/benchmarks/{benchmark_id}/jobs/{job_id}: + get: + responses: + '200': + description: The status of the evaluation job. + content: + application/json: + schema: + $ref: '#/components/schemas/Job' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Eval + summary: Get the status of a job. + description: Get the status of a job. + parameters: + - name: benchmark_id + in: path + description: >- + The ID of the benchmark to run the evaluation on. + required: true + schema: + type: string + - name: job_id + in: path + description: The ID of the job to get the status of. + required: true + schema: + type: string + deprecated: false + delete: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Eval + summary: Cancel a job. + description: Cancel a job. + parameters: + - name: benchmark_id + in: path + description: >- + The ID of the benchmark to run the evaluation on. + required: true + schema: + type: string + - name: job_id + in: path + description: The ID of the job to cancel. + required: true + schema: + type: string + deprecated: false + /v1alpha/eval/benchmarks/{benchmark_id}/jobs/{job_id}/result: + get: + responses: + '200': + description: The result of the job. + content: + application/json: + schema: + $ref: '#/components/schemas/EvaluateResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Eval + summary: Get the result of a job. + description: Get the result of a job. + parameters: + - name: benchmark_id + in: path + description: >- + The ID of the benchmark to run the evaluation on. + required: true + schema: + type: string + - name: job_id + in: path + description: The ID of the job to get the result of. + required: true + schema: + type: string + deprecated: false + /v1alpha/inference/rerank: + post: + responses: + '200': + description: >- + RerankResponse with indices sorted by relevance score (descending). + content: + application/json: + schema: + $ref: '#/components/schemas/RerankResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - Inference + summary: >- + Rerank a list of documents based on their relevance to a query. + description: >- + Rerank a list of documents based on their relevance to a query. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/RerankRequest' + required: true + deprecated: false + /v1alpha/post-training/job/artifacts: + get: + responses: + '200': + description: A PostTrainingJobArtifactsResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/PostTrainingJobArtifactsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - PostTraining (Coming Soon) + summary: Get the artifacts of a training job. + description: Get the artifacts of a training job. + parameters: + - name: job_uuid + in: query + description: >- + The UUID of the job to get the artifacts of. + required: true + schema: + type: string + deprecated: false + /v1alpha/post-training/job/cancel: + post: + responses: + '200': + description: OK + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - PostTraining (Coming Soon) + summary: Cancel a training job. + description: Cancel a training job. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/CancelTrainingJobRequest' + required: true + deprecated: false + /v1alpha/post-training/job/status: + get: + responses: + '200': + description: A PostTrainingJobStatusResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/PostTrainingJobStatusResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - PostTraining (Coming Soon) + summary: Get the status of a training job. + description: Get the status of a training job. + parameters: + - name: job_uuid + in: query + description: >- + The UUID of the job to get the status of. + required: true + schema: + type: string + deprecated: false + /v1alpha/post-training/jobs: + get: + responses: + '200': + description: A ListPostTrainingJobsResponse. + content: + application/json: + schema: + $ref: '#/components/schemas/ListPostTrainingJobsResponse' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - PostTraining (Coming Soon) + summary: Get all training jobs. + description: Get all training jobs. + parameters: [] + deprecated: false + /v1alpha/post-training/preference-optimize: + post: + responses: + '200': + description: A PostTrainingJob. + content: + application/json: + schema: + $ref: '#/components/schemas/PostTrainingJob' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - PostTraining (Coming Soon) + summary: Run preference optimization of a model. + description: Run preference optimization of a model. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/PreferenceOptimizeRequest' + required: true + deprecated: false + /v1alpha/post-training/supervised-fine-tune: + post: + responses: + '200': + description: A PostTrainingJob. + content: + application/json: + schema: + $ref: '#/components/schemas/PostTrainingJob' + '400': + $ref: '#/components/responses/BadRequest400' + '429': + $ref: >- + #/components/responses/TooManyRequests429 + '500': + $ref: >- + #/components/responses/InternalServerError500 + default: + $ref: '#/components/responses/DefaultError' + tags: + - PostTraining (Coming Soon) + summary: Run supervised fine-tuning of a model. + description: Run supervised fine-tuning of a model. + parameters: [] + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/SupervisedFineTuneRequest' + required: true + deprecated: false +jsonSchemaDialect: >- + https://json-schema.org/draft/2020-12/schema +components: + schemas: + Error: + type: object + properties: + status: + type: integer + description: HTTP status code + title: + type: string + description: >- + Error title, a short summary of the error which is invariant for an error + type + detail: + type: string + description: >- + Error detail, a longer human-readable description of the error + instance: + type: string + description: >- + (Optional) A URL which can be used to retrieve more information about + the specific occurrence of the error + additionalProperties: false + required: + - status + - title + - detail + title: Error + description: >- + Error response from the API. Roughly follows RFC 7807. + Order: + type: string + enum: + - asc + - desc + title: Order + description: Sort order for paginated responses. + ListOpenAIChatCompletionResponse: + type: object + properties: + data: + type: array + items: + type: object + properties: + id: + type: string + description: The ID of the chat completion + choices: + type: array + items: + $ref: '#/components/schemas/OpenAIChoice' + description: List of choices + object: + type: string + const: chat.completion + default: chat.completion + description: >- + The object type, which will be "chat.completion" + created: + type: integer + description: >- + The Unix timestamp in seconds when the chat completion was created + model: + type: string + description: >- + The model that was used to generate the chat completion + usage: + $ref: '#/components/schemas/OpenAIChatCompletionUsage' + description: >- + Token usage information for the completion + input_messages: + type: array + items: + $ref: '#/components/schemas/OpenAIMessageParam' + additionalProperties: false + required: + - id + - choices + - object + - created + - model + - input_messages + title: OpenAICompletionWithInputMessages + description: >- + List of chat completion objects with their input messages + has_more: + type: boolean + description: >- + Whether there are more completions available beyond this list + first_id: + type: string + description: ID of the first completion in this list + last_id: + type: string + description: ID of the last completion in this list + object: + type: string + const: list + default: list + description: >- + Must be "list" to identify this as a list response + additionalProperties: false + required: + - data + - has_more + - first_id + - last_id + - object + title: ListOpenAIChatCompletionResponse + description: >- + Response from listing OpenAI-compatible chat completions. + OpenAIAssistantMessageParam: + type: object + properties: + role: + type: string + const: assistant + default: assistant + description: >- + Must be "assistant" to identify this as the model's response + content: + oneOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/OpenAIChatCompletionContentPartTextParam' + description: The content of the model's response + name: + type: string + description: >- + (Optional) The name of the assistant message participant. + tool_calls: + type: array + items: + $ref: '#/components/schemas/OpenAIChatCompletionToolCall' + description: >- + List of tool calls. Each tool call is an OpenAIChatCompletionToolCall + object. + additionalProperties: false + required: + - role + title: OpenAIAssistantMessageParam + description: >- + A message containing the model's (assistant) response in an OpenAI-compatible + chat completion request. + "OpenAIChatCompletionContentPartImageParam": + type: object + properties: + type: + type: string + const: image_url + default: image_url + description: >- + Must be "image_url" to identify this as image content + image_url: + $ref: '#/components/schemas/OpenAIImageURL' + description: >- + Image URL specification and processing details + additionalProperties: false + required: + - type + - image_url + title: >- + OpenAIChatCompletionContentPartImageParam + description: >- + Image content part for OpenAI-compatible chat completion messages. + OpenAIChatCompletionContentPartParam: + oneOf: + - $ref: '#/components/schemas/OpenAIChatCompletionContentPartTextParam' + - $ref: '#/components/schemas/OpenAIChatCompletionContentPartImageParam' + - $ref: '#/components/schemas/OpenAIFile' + discriminator: + propertyName: type + mapping: + text: '#/components/schemas/OpenAIChatCompletionContentPartTextParam' + image_url: '#/components/schemas/OpenAIChatCompletionContentPartImageParam' + file: '#/components/schemas/OpenAIFile' + OpenAIChatCompletionContentPartTextParam: + type: object + properties: + type: + type: string + const: text + default: text + description: >- + Must be "text" to identify this as text content + text: + type: string + description: The text content of the message + additionalProperties: false + required: + - type + - text + title: OpenAIChatCompletionContentPartTextParam + description: >- + Text content part for OpenAI-compatible chat completion messages. + OpenAIChatCompletionToolCall: + type: object + properties: + index: + type: integer + description: >- + (Optional) Index of the tool call in the list + id: + type: string + description: >- + (Optional) Unique identifier for the tool call + type: + type: string + const: function + default: function + description: >- + Must be "function" to identify this as a function call + function: + $ref: '#/components/schemas/OpenAIChatCompletionToolCallFunction' + description: (Optional) Function call details + additionalProperties: false + required: + - type + title: OpenAIChatCompletionToolCall + description: >- + Tool call specification for OpenAI-compatible chat completion responses. + OpenAIChatCompletionToolCallFunction: + type: object + properties: + name: + type: string + description: (Optional) Name of the function to call + arguments: + type: string + description: >- + (Optional) Arguments to pass to the function as a JSON string + additionalProperties: false + title: OpenAIChatCompletionToolCallFunction + description: >- + Function call details for OpenAI-compatible tool calls. + OpenAIChatCompletionUsage: + type: object + properties: + prompt_tokens: + type: integer + description: Number of tokens in the prompt + completion_tokens: + type: integer + description: Number of tokens in the completion + total_tokens: + type: integer + description: Total tokens used (prompt + completion) + prompt_tokens_details: + type: object + properties: + cached_tokens: + type: integer + description: Number of tokens retrieved from cache + additionalProperties: false + title: >- + OpenAIChatCompletionUsagePromptTokensDetails + description: >- + Token details for prompt tokens in OpenAI chat completion usage. + completion_tokens_details: + type: object + properties: + reasoning_tokens: + type: integer + description: >- + Number of tokens used for reasoning (o1/o3 models) + additionalProperties: false + title: >- + OpenAIChatCompletionUsageCompletionTokensDetails + description: >- + Token details for output tokens in OpenAI chat completion usage. + additionalProperties: false + required: + - prompt_tokens + - completion_tokens + - total_tokens + title: OpenAIChatCompletionUsage + description: >- + Usage information for OpenAI chat completion. + OpenAIChoice: + type: object + properties: + message: + oneOf: + - $ref: '#/components/schemas/OpenAIUserMessageParam' + - $ref: '#/components/schemas/OpenAISystemMessageParam' + - $ref: '#/components/schemas/OpenAIAssistantMessageParam' + - $ref: '#/components/schemas/OpenAIToolMessageParam' + - $ref: '#/components/schemas/OpenAIDeveloperMessageParam' + discriminator: + propertyName: role + mapping: + user: '#/components/schemas/OpenAIUserMessageParam' + system: '#/components/schemas/OpenAISystemMessageParam' + assistant: '#/components/schemas/OpenAIAssistantMessageParam' + tool: '#/components/schemas/OpenAIToolMessageParam' + developer: '#/components/schemas/OpenAIDeveloperMessageParam' + description: The message from the model + finish_reason: + type: string + description: The reason the model stopped generating + index: + type: integer + description: The index of the choice + logprobs: + $ref: '#/components/schemas/OpenAIChoiceLogprobs' + description: >- + (Optional) The log probabilities for the tokens in the message + additionalProperties: false + required: + - message + - finish_reason + - index + title: OpenAIChoice + description: >- + A choice from an OpenAI-compatible chat completion response. + OpenAIChoiceLogprobs: + type: object + properties: + content: + type: array + items: + $ref: '#/components/schemas/OpenAITokenLogProb' + description: >- + (Optional) The log probabilities for the tokens in the message + refusal: + type: array + items: + $ref: '#/components/schemas/OpenAITokenLogProb' + description: >- + (Optional) The log probabilities for the tokens in the message + additionalProperties: false + title: OpenAIChoiceLogprobs + description: >- + The log probabilities for the tokens in the message from an OpenAI-compatible + chat completion response. + OpenAIDeveloperMessageParam: + type: object + properties: + role: + type: string + const: developer + default: developer + description: >- + Must be "developer" to identify this as a developer message + content: + oneOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/OpenAIChatCompletionContentPartTextParam' + description: The content of the developer message + name: + type: string + description: >- + (Optional) The name of the developer message participant. + additionalProperties: false + required: + - role + - content + title: OpenAIDeveloperMessageParam + description: >- + A message from the developer in an OpenAI-compatible chat completion request. + OpenAIFile: + type: object + properties: + type: + type: string + const: file + default: file + file: + $ref: '#/components/schemas/OpenAIFileFile' + additionalProperties: false + required: + - type + - file + title: OpenAIFile + OpenAIFileFile: + type: object + properties: + file_data: + type: string + file_id: + type: string + filename: + type: string + additionalProperties: false + title: OpenAIFileFile + OpenAIImageURL: + type: object + properties: + url: + type: string + description: >- + URL of the image to include in the message + detail: + type: string + description: >- + (Optional) Level of detail for image processing. Can be "low", "high", + or "auto" + additionalProperties: false + required: + - url + title: OpenAIImageURL + description: >- + Image URL specification for OpenAI-compatible chat completion messages. + OpenAIMessageParam: + oneOf: + - $ref: '#/components/schemas/OpenAIUserMessageParam' + - $ref: '#/components/schemas/OpenAISystemMessageParam' + - $ref: '#/components/schemas/OpenAIAssistantMessageParam' + - $ref: '#/components/schemas/OpenAIToolMessageParam' + - $ref: '#/components/schemas/OpenAIDeveloperMessageParam' + discriminator: + propertyName: role + mapping: + user: '#/components/schemas/OpenAIUserMessageParam' + system: '#/components/schemas/OpenAISystemMessageParam' + assistant: '#/components/schemas/OpenAIAssistantMessageParam' + tool: '#/components/schemas/OpenAIToolMessageParam' + developer: '#/components/schemas/OpenAIDeveloperMessageParam' + OpenAISystemMessageParam: + type: object + properties: + role: + type: string + const: system + default: system + description: >- + Must be "system" to identify this as a system message + content: + oneOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/OpenAIChatCompletionContentPartTextParam' + description: >- + The content of the "system prompt". If multiple system messages are provided, + they are concatenated. The underlying Llama Stack code may also add other + system messages (for example, for formatting tool definitions). + name: + type: string + description: >- + (Optional) The name of the system message participant. + additionalProperties: false + required: + - role + - content + title: OpenAISystemMessageParam + description: >- + A system message providing instructions or context to the model. + OpenAITokenLogProb: + type: object + properties: + token: + type: string + bytes: + type: array + items: + type: integer + logprob: + type: number + top_logprobs: + type: array + items: + $ref: '#/components/schemas/OpenAITopLogProb' + additionalProperties: false + required: + - token + - logprob + - top_logprobs + title: OpenAITokenLogProb + description: >- + The log probability for a token from an OpenAI-compatible chat completion + response. + OpenAIToolMessageParam: + type: object + properties: + role: + type: string + const: tool + default: tool + description: >- + Must be "tool" to identify this as a tool response + tool_call_id: + type: string + description: >- + Unique identifier for the tool call this response is for + content: + oneOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/OpenAIChatCompletionContentPartTextParam' + description: The response content from the tool + additionalProperties: false + required: + - role + - tool_call_id + - content + title: OpenAIToolMessageParam + description: >- + A message representing the result of a tool invocation in an OpenAI-compatible + chat completion request. + OpenAITopLogProb: + type: object + properties: + token: + type: string + bytes: + type: array + items: + type: integer + logprob: + type: number + additionalProperties: false + required: + - token + - logprob + title: OpenAITopLogProb + description: >- + The top log probability for a token from an OpenAI-compatible chat completion + response. + OpenAIUserMessageParam: + type: object + properties: + role: + type: string + const: user + default: user + description: >- + Must be "user" to identify this as a user message + content: + oneOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/OpenAIChatCompletionContentPartParam' + description: >- + The content of the message, which can include text and other media + name: + type: string + description: >- + (Optional) The name of the user message participant. + additionalProperties: false + required: + - role + - content + title: OpenAIUserMessageParam + description: >- + A message from the user in an OpenAI-compatible chat completion request. + OpenAIJSONSchema: + type: object + properties: + name: + type: string + description: Name of the schema + description: + type: string + description: (Optional) Description of the schema + strict: + type: boolean + description: >- + (Optional) Whether to enforce strict adherence to the schema + schema: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: (Optional) The JSON schema definition + additionalProperties: false + required: + - name + title: OpenAIJSONSchema + description: >- + JSON schema specification for OpenAI-compatible structured response format. + OpenAIResponseFormatJSONObject: + type: object + properties: + type: + type: string + const: json_object + default: json_object + description: >- + Must be "json_object" to indicate generic JSON object response format + additionalProperties: false + required: + - type + title: OpenAIResponseFormatJSONObject + description: >- + JSON object response format for OpenAI-compatible chat completion requests. + OpenAIResponseFormatJSONSchema: + type: object + properties: + type: + type: string + const: json_schema + default: json_schema + description: >- + Must be "json_schema" to indicate structured JSON response format + json_schema: + $ref: '#/components/schemas/OpenAIJSONSchema' + description: >- + The JSON schema specification for the response + additionalProperties: false + required: + - type + - json_schema + title: OpenAIResponseFormatJSONSchema + description: >- + JSON schema response format for OpenAI-compatible chat completion requests. + OpenAIResponseFormatParam: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseFormatText' + - $ref: '#/components/schemas/OpenAIResponseFormatJSONSchema' + - $ref: '#/components/schemas/OpenAIResponseFormatJSONObject' + discriminator: + propertyName: type + mapping: + text: '#/components/schemas/OpenAIResponseFormatText' + json_schema: '#/components/schemas/OpenAIResponseFormatJSONSchema' + json_object: '#/components/schemas/OpenAIResponseFormatJSONObject' + OpenAIResponseFormatText: + type: object + properties: + type: + type: string + const: text + default: text + description: >- + Must be "text" to indicate plain text response format + additionalProperties: false + required: + - type + title: OpenAIResponseFormatText + description: >- + Text response format for OpenAI-compatible chat completion requests. + OpenAIChatCompletionRequestWithExtraBody: + type: object + properties: + model: + type: string + description: >- + The identifier of the model to use. The model must be registered with + Llama Stack and available via the /models endpoint. + messages: + type: array + items: + $ref: '#/components/schemas/OpenAIMessageParam' + description: List of messages in the conversation. + frequency_penalty: + type: number + description: >- + (Optional) The penalty for repeated tokens. + function_call: + oneOf: + - type: string + - type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: (Optional) The function call to use. + functions: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: (Optional) List of functions to use. + logit_bias: + type: object + additionalProperties: + type: number + description: (Optional) The logit bias to use. + logprobs: + type: boolean + description: (Optional) The log probabilities to use. + max_completion_tokens: + type: integer + description: >- + (Optional) The maximum number of tokens to generate. + max_tokens: + type: integer + description: >- + (Optional) The maximum number of tokens to generate. + n: + type: integer + description: >- + (Optional) The number of completions to generate. + parallel_tool_calls: + type: boolean + description: >- + (Optional) Whether to parallelize tool calls. + presence_penalty: + type: number + description: >- + (Optional) The penalty for repeated tokens. + response_format: + $ref: '#/components/schemas/OpenAIResponseFormatParam' + description: (Optional) The response format to use. + seed: + type: integer + description: (Optional) The seed to use. + stop: + oneOf: + - type: string + - type: array + items: + type: string + description: (Optional) The stop tokens to use. + stream: + type: boolean + description: >- + (Optional) Whether to stream the response. + stream_options: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: (Optional) The stream options to use. + temperature: + type: number + description: (Optional) The temperature to use. + tool_choice: + oneOf: + - type: string + - type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: (Optional) The tool choice to use. + tools: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: (Optional) The tools to use. + top_logprobs: + type: integer + description: >- + (Optional) The top log probabilities to use. + top_p: + type: number + description: (Optional) The top p to use. + user: + type: string + description: (Optional) The user to use. + additionalProperties: false + required: + - model + - messages + title: OpenAIChatCompletionRequestWithExtraBody + description: >- + Request parameters for OpenAI-compatible chat completion endpoint. + OpenAIChatCompletion: + type: object + properties: + id: + type: string + description: The ID of the chat completion + choices: + type: array + items: + $ref: '#/components/schemas/OpenAIChoice' + description: List of choices + object: + type: string + const: chat.completion + default: chat.completion + description: >- + The object type, which will be "chat.completion" + created: + type: integer + description: >- + The Unix timestamp in seconds when the chat completion was created + model: + type: string + description: >- + The model that was used to generate the chat completion + usage: + $ref: '#/components/schemas/OpenAIChatCompletionUsage' + description: >- + Token usage information for the completion + additionalProperties: false + required: + - id + - choices + - object + - created + - model + title: OpenAIChatCompletion + description: >- + Response from an OpenAI-compatible chat completion request. + OpenAIChatCompletionChunk: + type: object + properties: + id: + type: string + description: The ID of the chat completion + choices: + type: array + items: + $ref: '#/components/schemas/OpenAIChunkChoice' + description: List of choices + object: + type: string + const: chat.completion.chunk + default: chat.completion.chunk + description: >- + The object type, which will be "chat.completion.chunk" + created: + type: integer + description: >- + The Unix timestamp in seconds when the chat completion was created + model: + type: string + description: >- + The model that was used to generate the chat completion + usage: + $ref: '#/components/schemas/OpenAIChatCompletionUsage' + description: >- + Token usage information (typically included in final chunk with stream_options) + additionalProperties: false + required: + - id + - choices + - object + - created + - model + title: OpenAIChatCompletionChunk + description: >- + Chunk from a streaming response to an OpenAI-compatible chat completion request. + OpenAIChoiceDelta: + type: object + properties: + content: + type: string + description: (Optional) The content of the delta + refusal: + type: string + description: (Optional) The refusal of the delta + role: + type: string + description: (Optional) The role of the delta + tool_calls: + type: array + items: + $ref: '#/components/schemas/OpenAIChatCompletionToolCall' + description: (Optional) The tool calls of the delta + reasoning_content: + type: string + description: >- + (Optional) The reasoning content from the model (non-standard, for o1/o3 + models) + additionalProperties: false + title: OpenAIChoiceDelta + description: >- + A delta from an OpenAI-compatible chat completion streaming response. + OpenAIChunkChoice: + type: object + properties: + delta: + $ref: '#/components/schemas/OpenAIChoiceDelta' + description: The delta from the chunk + finish_reason: + type: string + description: The reason the model stopped generating + index: + type: integer + description: The index of the choice + logprobs: + $ref: '#/components/schemas/OpenAIChoiceLogprobs' + description: >- + (Optional) The log probabilities for the tokens in the message + additionalProperties: false + required: + - delta + - finish_reason + - index + title: OpenAIChunkChoice + description: >- + A chunk choice from an OpenAI-compatible chat completion streaming response. + OpenAICompletionWithInputMessages: + type: object + properties: + id: + type: string + description: The ID of the chat completion + choices: + type: array + items: + $ref: '#/components/schemas/OpenAIChoice' + description: List of choices + object: + type: string + const: chat.completion + default: chat.completion + description: >- + The object type, which will be "chat.completion" + created: + type: integer + description: >- + The Unix timestamp in seconds when the chat completion was created + model: + type: string + description: >- + The model that was used to generate the chat completion + usage: + $ref: '#/components/schemas/OpenAIChatCompletionUsage' + description: >- + Token usage information for the completion + input_messages: + type: array + items: + $ref: '#/components/schemas/OpenAIMessageParam' + additionalProperties: false + required: + - id + - choices + - object + - created + - model + - input_messages + title: OpenAICompletionWithInputMessages + OpenAICompletionRequestWithExtraBody: + type: object + properties: + model: + type: string + description: >- + The identifier of the model to use. The model must be registered with + Llama Stack and available via the /models endpoint. + prompt: + oneOf: + - type: string + - type: array + items: + type: string + - type: array + items: + type: integer + - type: array + items: + type: array + items: + type: integer + description: The prompt to generate a completion for. + best_of: + type: integer + description: >- + (Optional) The number of completions to generate. + echo: + type: boolean + description: (Optional) Whether to echo the prompt. + frequency_penalty: + type: number + description: >- + (Optional) The penalty for repeated tokens. + logit_bias: + type: object + additionalProperties: + type: number + description: (Optional) The logit bias to use. + logprobs: + type: boolean + description: (Optional) The log probabilities to use. + max_tokens: + type: integer + description: >- + (Optional) The maximum number of tokens to generate. + n: + type: integer + description: >- + (Optional) The number of completions to generate. + presence_penalty: + type: number + description: >- + (Optional) The penalty for repeated tokens. + seed: + type: integer + description: (Optional) The seed to use. + stop: + oneOf: + - type: string + - type: array + items: + type: string + description: (Optional) The stop tokens to use. + stream: + type: boolean + description: >- + (Optional) Whether to stream the response. + stream_options: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: (Optional) The stream options to use. + temperature: + type: number + description: (Optional) The temperature to use. + top_p: + type: number + description: (Optional) The top p to use. + user: + type: string + description: (Optional) The user to use. + suffix: + type: string + description: >- + (Optional) The suffix that should be appended to the completion. + additionalProperties: false + required: + - model + - prompt + title: OpenAICompletionRequestWithExtraBody + description: >- + Request parameters for OpenAI-compatible completion endpoint. + OpenAICompletion: + type: object + properties: + id: + type: string + choices: + type: array + items: + $ref: '#/components/schemas/OpenAICompletionChoice' + created: + type: integer + model: + type: string + object: + type: string + const: text_completion + default: text_completion + additionalProperties: false + required: + - id + - choices + - created + - model + - object + title: OpenAICompletion + description: >- + Response from an OpenAI-compatible completion request. + OpenAICompletionChoice: + type: object + properties: + finish_reason: + type: string + text: + type: string + index: + type: integer + logprobs: + $ref: '#/components/schemas/OpenAIChoiceLogprobs' + additionalProperties: false + required: + - finish_reason + - text + - index + title: OpenAICompletionChoice + description: >- + A choice from an OpenAI-compatible completion response. + ConversationItem: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseMessage' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageWebSearchToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageFileSearchToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageFunctionToolCall' + - $ref: '#/components/schemas/OpenAIResponseInputFunctionToolCallOutput' + - $ref: '#/components/schemas/OpenAIResponseMCPApprovalRequest' + - $ref: '#/components/schemas/OpenAIResponseMCPApprovalResponse' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageMCPCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageMCPListTools' + discriminator: + propertyName: type + mapping: + message: '#/components/schemas/OpenAIResponseMessage' + web_search_call: '#/components/schemas/OpenAIResponseOutputMessageWebSearchToolCall' + file_search_call: '#/components/schemas/OpenAIResponseOutputMessageFileSearchToolCall' + function_call: '#/components/schemas/OpenAIResponseOutputMessageFunctionToolCall' + function_call_output: '#/components/schemas/OpenAIResponseInputFunctionToolCallOutput' + mcp_approval_request: '#/components/schemas/OpenAIResponseMCPApprovalRequest' + mcp_approval_response: '#/components/schemas/OpenAIResponseMCPApprovalResponse' + mcp_call: '#/components/schemas/OpenAIResponseOutputMessageMCPCall' + mcp_list_tools: '#/components/schemas/OpenAIResponseOutputMessageMCPListTools' + OpenAIResponseAnnotationCitation: + type: object + properties: + type: + type: string + const: url_citation + default: url_citation + description: >- + Annotation type identifier, always "url_citation" + end_index: + type: integer + description: >- + End position of the citation span in the content + start_index: + type: integer + description: >- + Start position of the citation span in the content + title: + type: string + description: Title of the referenced web resource + url: + type: string + description: URL of the referenced web resource + additionalProperties: false + required: + - type + - end_index + - start_index + - title + - url + title: OpenAIResponseAnnotationCitation + description: >- + URL citation annotation for referencing external web resources. + "OpenAIResponseAnnotationContainerFileCitation": + type: object + properties: + type: + type: string + const: container_file_citation + default: container_file_citation + container_id: + type: string + end_index: + type: integer + file_id: + type: string + filename: + type: string + start_index: + type: integer + additionalProperties: false + required: + - type + - container_id + - end_index + - file_id + - filename + - start_index + title: >- + OpenAIResponseAnnotationContainerFileCitation + OpenAIResponseAnnotationFileCitation: + type: object + properties: + type: + type: string + const: file_citation + default: file_citation + description: >- + Annotation type identifier, always "file_citation" + file_id: + type: string + description: Unique identifier of the referenced file + filename: + type: string + description: Name of the referenced file + index: + type: integer + description: >- + Position index of the citation within the content + additionalProperties: false + required: + - type + - file_id + - filename + - index + title: OpenAIResponseAnnotationFileCitation + description: >- + File citation annotation for referencing specific files in response content. + OpenAIResponseAnnotationFilePath: + type: object + properties: + type: + type: string + const: file_path + default: file_path + file_id: + type: string + index: + type: integer + additionalProperties: false + required: + - type + - file_id + - index + title: OpenAIResponseAnnotationFilePath + OpenAIResponseAnnotations: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseAnnotationFileCitation' + - $ref: '#/components/schemas/OpenAIResponseAnnotationCitation' + - $ref: '#/components/schemas/OpenAIResponseAnnotationContainerFileCitation' + - $ref: '#/components/schemas/OpenAIResponseAnnotationFilePath' + discriminator: + propertyName: type + mapping: + file_citation: '#/components/schemas/OpenAIResponseAnnotationFileCitation' + url_citation: '#/components/schemas/OpenAIResponseAnnotationCitation' + container_file_citation: '#/components/schemas/OpenAIResponseAnnotationContainerFileCitation' + file_path: '#/components/schemas/OpenAIResponseAnnotationFilePath' + OpenAIResponseContentPartRefusal: + type: object + properties: + type: + type: string + const: refusal + default: refusal + description: >- + Content part type identifier, always "refusal" + refusal: + type: string + description: Refusal text supplied by the model + additionalProperties: false + required: + - type + - refusal + title: OpenAIResponseContentPartRefusal + description: >- + Refusal content within a streamed response part. + "OpenAIResponseInputFunctionToolCallOutput": + type: object + properties: + call_id: + type: string + output: + type: string + type: + type: string + const: function_call_output + default: function_call_output + id: + type: string + status: + type: string + additionalProperties: false + required: + - call_id + - output + - type + title: >- + OpenAIResponseInputFunctionToolCallOutput + description: >- + This represents the output of a function call that gets passed back to the + model. + OpenAIResponseInputMessageContent: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseInputMessageContentText' + - $ref: '#/components/schemas/OpenAIResponseInputMessageContentImage' + discriminator: + propertyName: type + mapping: + input_text: '#/components/schemas/OpenAIResponseInputMessageContentText' + input_image: '#/components/schemas/OpenAIResponseInputMessageContentImage' + OpenAIResponseInputMessageContentImage: + type: object + properties: + detail: + oneOf: + - type: string + const: low + - type: string + const: high + - type: string + const: auto + default: auto + description: >- + Level of detail for image processing, can be "low", "high", or "auto" + type: + type: string + const: input_image + default: input_image + description: >- + Content type identifier, always "input_image" + image_url: + type: string + description: (Optional) URL of the image content + additionalProperties: false + required: + - detail + - type + title: OpenAIResponseInputMessageContentImage + description: >- + Image content for input messages in OpenAI response format. + OpenAIResponseInputMessageContentText: + type: object + properties: + text: + type: string + description: The text content of the input message + type: + type: string + const: input_text + default: input_text + description: >- + Content type identifier, always "input_text" + additionalProperties: false + required: + - text + - type + title: OpenAIResponseInputMessageContentText + description: >- + Text content for input messages in OpenAI response format. + OpenAIResponseMCPApprovalRequest: + type: object + properties: + arguments: + type: string + id: + type: string + name: + type: string + server_label: + type: string + type: + type: string + const: mcp_approval_request + default: mcp_approval_request + additionalProperties: false + required: + - arguments + - id + - name + - server_label + - type + title: OpenAIResponseMCPApprovalRequest + description: >- + A request for human approval of a tool invocation. + OpenAIResponseMCPApprovalResponse: + type: object + properties: + approval_request_id: + type: string + approve: + type: boolean + type: + type: string + const: mcp_approval_response + default: mcp_approval_response + id: + type: string + reason: + type: string + additionalProperties: false + required: + - approval_request_id + - approve + - type + title: OpenAIResponseMCPApprovalResponse + description: A response to an MCP approval request. + OpenAIResponseMessage: + type: object + properties: + content: + oneOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/OpenAIResponseInputMessageContent' + - type: array + items: + $ref: '#/components/schemas/OpenAIResponseOutputMessageContent' + role: + oneOf: + - type: string + const: system + - type: string + const: developer + - type: string + const: user + - type: string + const: assistant + type: + type: string + const: message + default: message + id: + type: string + status: + type: string + additionalProperties: false + required: + - content + - role + - type + title: OpenAIResponseMessage + description: >- + Corresponds to the various Message types in the Responses API. They are all + under one type because the Responses API gives them all the same "type" value, + and there is no way to tell them apart in certain scenarios. + OpenAIResponseOutputMessageContent: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseOutputMessageContentOutputText' + - $ref: '#/components/schemas/OpenAIResponseContentPartRefusal' + discriminator: + propertyName: type + mapping: + output_text: '#/components/schemas/OpenAIResponseOutputMessageContentOutputText' + refusal: '#/components/schemas/OpenAIResponseContentPartRefusal' + "OpenAIResponseOutputMessageContentOutputText": + type: object + properties: + text: + type: string + type: + type: string + const: output_text + default: output_text + annotations: + type: array + items: + $ref: '#/components/schemas/OpenAIResponseAnnotations' + additionalProperties: false + required: + - text + - type + - annotations + title: >- + OpenAIResponseOutputMessageContentOutputText + "OpenAIResponseOutputMessageFileSearchToolCall": + type: object + properties: + id: + type: string + description: Unique identifier for this tool call + queries: + type: array + items: + type: string + description: List of search queries executed + status: + type: string + description: >- + Current status of the file search operation + type: + type: string + const: file_search_call + default: file_search_call + description: >- + Tool call type identifier, always "file_search_call" + results: + type: array + items: + type: object + properties: + attributes: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Key-value attributes associated with the file + file_id: + type: string + description: >- + Unique identifier of the file containing the result + filename: + type: string + description: Name of the file containing the result + score: + type: number + description: >- + Relevance score for this search result (between 0 and 1) + text: + type: string + description: Text content of the search result + additionalProperties: false + required: + - attributes + - file_id + - filename + - score + - text + title: >- + OpenAIResponseOutputMessageFileSearchToolCallResults + description: >- + Search results returned by the file search operation. + description: >- + (Optional) Search results returned by the file search operation + additionalProperties: false + required: + - id + - queries + - status + - type + title: >- + OpenAIResponseOutputMessageFileSearchToolCall + description: >- + File search tool call output message for OpenAI responses. + "OpenAIResponseOutputMessageFunctionToolCall": + type: object + properties: + call_id: + type: string + description: Unique identifier for the function call + name: + type: string + description: Name of the function being called + arguments: + type: string + description: >- + JSON string containing the function arguments + type: + type: string + const: function_call + default: function_call + description: >- + Tool call type identifier, always "function_call" + id: + type: string + description: >- + (Optional) Additional identifier for the tool call + status: + type: string + description: >- + (Optional) Current status of the function call execution + additionalProperties: false + required: + - call_id + - name + - arguments + - type + title: >- + OpenAIResponseOutputMessageFunctionToolCall + description: >- + Function tool call output message for OpenAI responses. + OpenAIResponseOutputMessageMCPCall: + type: object + properties: + id: + type: string + description: Unique identifier for this MCP call + type: + type: string + const: mcp_call + default: mcp_call + description: >- + Tool call type identifier, always "mcp_call" + arguments: + type: string + description: >- + JSON string containing the MCP call arguments + name: + type: string + description: Name of the MCP method being called + server_label: + type: string + description: >- + Label identifying the MCP server handling the call + error: + type: string + description: >- + (Optional) Error message if the MCP call failed + output: + type: string + description: >- + (Optional) Output result from the successful MCP call + additionalProperties: false + required: + - id + - type + - arguments + - name + - server_label + title: OpenAIResponseOutputMessageMCPCall + description: >- + Model Context Protocol (MCP) call output message for OpenAI responses. + OpenAIResponseOutputMessageMCPListTools: + type: object + properties: + id: + type: string + description: >- + Unique identifier for this MCP list tools operation + type: + type: string + const: mcp_list_tools + default: mcp_list_tools + description: >- + Tool call type identifier, always "mcp_list_tools" + server_label: + type: string + description: >- + Label identifying the MCP server providing the tools + tools: + type: array + items: + type: object + properties: + input_schema: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + JSON schema defining the tool's input parameters + name: + type: string + description: Name of the tool + description: + type: string + description: >- + (Optional) Description of what the tool does + additionalProperties: false + required: + - input_schema + - name + title: MCPListToolsTool + description: >- + Tool definition returned by MCP list tools operation. + description: >- + List of available tools provided by the MCP server + additionalProperties: false + required: + - id + - type + - server_label + - tools + title: OpenAIResponseOutputMessageMCPListTools + description: >- + MCP list tools output message containing available tools from an MCP server. + "OpenAIResponseOutputMessageWebSearchToolCall": + type: object + properties: + id: + type: string + description: Unique identifier for this tool call + status: + type: string + description: >- + Current status of the web search operation + type: + type: string + const: web_search_call + default: web_search_call + description: >- + Tool call type identifier, always "web_search_call" + additionalProperties: false + required: + - id + - status + - type + title: >- + OpenAIResponseOutputMessageWebSearchToolCall + description: >- + Web search tool call output message for OpenAI responses. + CreateConversationRequest: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/ConversationItem' + description: >- + Initial items to include in the conversation context. + metadata: + type: object + additionalProperties: + type: string + description: >- + Set of key-value pairs that can be attached to an object. + additionalProperties: false + title: CreateConversationRequest + Conversation: + type: object + properties: + id: + type: string + object: + type: string + const: conversation + default: conversation + created_at: + type: integer + metadata: + type: object + additionalProperties: + type: string + items: + type: array + items: + type: object + title: dict + description: >- + dict() -> new empty dictionary dict(mapping) -> new dictionary initialized + from a mapping object's (key, value) pairs dict(iterable) -> new + dictionary initialized as if via: d = {} for k, v in iterable: d[k] + = v dict(**kwargs) -> new dictionary initialized with the name=value + pairs in the keyword argument list. For example: dict(one=1, two=2) + additionalProperties: false + required: + - id + - object + - created_at + title: Conversation + description: OpenAI-compatible conversation object. + UpdateConversationRequest: + type: object + properties: + metadata: + type: object + additionalProperties: + type: string + description: >- + Set of key-value pairs that can be attached to an object. + additionalProperties: false + required: + - metadata + title: UpdateConversationRequest + ConversationDeletedResource: + type: object + properties: + id: + type: string + object: + type: string + default: conversation.deleted + deleted: + type: boolean + default: true + additionalProperties: false + required: + - id + - object + - deleted + title: ConversationDeletedResource + description: Response for deleted conversation. + ConversationItemList: + type: object + properties: + object: + type: string + default: list + data: + type: array + items: + $ref: '#/components/schemas/ConversationItem' + first_id: + type: string + last_id: + type: string + has_more: + type: boolean + default: false + additionalProperties: false + required: + - object + - data + - has_more + title: ConversationItemList + description: >- + List of conversation items with pagination. + AddItemsRequest: + type: object + properties: + items: + type: array + items: + $ref: '#/components/schemas/ConversationItem' + description: >- + Items to include in the conversation context. + additionalProperties: false + required: + - items + title: AddItemsRequest + ConversationItemDeletedResource: + type: object + properties: + id: + type: string + object: + type: string + default: conversation.item.deleted + deleted: + type: boolean + default: true + additionalProperties: false + required: + - id + - object + - deleted + title: ConversationItemDeletedResource + description: Response for deleted conversation item. + OpenAIEmbeddingsRequestWithExtraBody: + type: object + properties: + model: + type: string + description: >- + The identifier of the model to use. The model must be an embedding model + registered with Llama Stack and available via the /models endpoint. + input: + oneOf: + - type: string + - type: array + items: + type: string + description: >- + Input text to embed, encoded as a string or array of strings. To embed + multiple inputs in a single request, pass an array of strings. + encoding_format: + type: string + default: float + description: >- + (Optional) The format to return the embeddings in. Can be either "float" + or "base64". Defaults to "float". + dimensions: + type: integer + description: >- + (Optional) The number of dimensions the resulting output embeddings should + have. Only supported in text-embedding-3 and later models. + user: + type: string + description: >- + (Optional) A unique identifier representing your end-user, which can help + OpenAI to monitor and detect abuse. + additionalProperties: false + required: + - model + - input + title: OpenAIEmbeddingsRequestWithExtraBody + description: >- + Request parameters for OpenAI-compatible embeddings endpoint. + OpenAIEmbeddingData: + type: object + properties: + object: + type: string + const: embedding + default: embedding + description: >- + The object type, which will be "embedding" + embedding: + oneOf: + - type: array + items: + type: number + - type: string + description: >- + The embedding vector as a list of floats (when encoding_format="float") + or as a base64-encoded string (when encoding_format="base64") + index: + type: integer + description: >- + The index of the embedding in the input list + additionalProperties: false + required: + - object + - embedding + - index + title: OpenAIEmbeddingData + description: >- + A single embedding data object from an OpenAI-compatible embeddings response. + OpenAIEmbeddingUsage: + type: object + properties: + prompt_tokens: + type: integer + description: The number of tokens in the input + total_tokens: + type: integer + description: The total number of tokens used + additionalProperties: false + required: + - prompt_tokens + - total_tokens + title: OpenAIEmbeddingUsage + description: >- + Usage information for an OpenAI-compatible embeddings response. + OpenAIEmbeddingsResponse: + type: object + properties: + object: + type: string + const: list + default: list + description: The object type, which will be "list" + data: + type: array + items: + $ref: '#/components/schemas/OpenAIEmbeddingData' + description: List of embedding data objects + model: + type: string + description: >- + The model that was used to generate the embeddings + usage: + $ref: '#/components/schemas/OpenAIEmbeddingUsage' + description: Usage information + additionalProperties: false + required: + - object + - data + - model + - usage + title: OpenAIEmbeddingsResponse + description: >- + Response from an OpenAI-compatible embeddings request. + OpenAIFilePurpose: + type: string + enum: + - assistants + - batch + title: OpenAIFilePurpose + description: >- + Valid purpose values for OpenAI Files API. + ListOpenAIFileResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/OpenAIFileObject' + description: List of file objects + has_more: + type: boolean + description: >- + Whether there are more files available beyond this page + first_id: + type: string + description: >- + ID of the first file in the list for pagination + last_id: + type: string + description: >- + ID of the last file in the list for pagination + object: + type: string + const: list + default: list + description: The object type, which is always "list" + additionalProperties: false + required: + - data + - has_more + - first_id + - last_id + - object + title: ListOpenAIFileResponse + description: >- + Response for listing files in OpenAI Files API. + OpenAIFileObject: + type: object + properties: + object: + type: string + const: file + default: file + description: The object type, which is always "file" + id: + type: string + description: >- + The file identifier, which can be referenced in the API endpoints + bytes: + type: integer + description: The size of the file, in bytes + created_at: + type: integer + description: >- + The Unix timestamp (in seconds) for when the file was created + expires_at: + type: integer + description: >- + The Unix timestamp (in seconds) for when the file expires + filename: + type: string + description: The name of the file + purpose: + type: string + enum: + - assistants + - batch + description: The intended purpose of the file + additionalProperties: false + required: + - object + - id + - bytes + - created_at + - expires_at + - filename + - purpose + title: OpenAIFileObject + description: >- + OpenAI File object as defined in the OpenAI Files API. + ExpiresAfter: + type: object + properties: + anchor: + type: string + const: created_at + seconds: + type: integer + additionalProperties: false + required: + - anchor + - seconds + title: ExpiresAfter + description: >- + Control expiration of uploaded files. + + Params: + - anchor, must be "created_at" + - seconds, must be int between 3600 and 2592000 (1 hour to 30 days) + OpenAIFileDeleteResponse: + type: object + properties: + id: + type: string + description: The file identifier that was deleted + object: + type: string + const: file + default: file + description: The object type, which is always "file" + deleted: + type: boolean + description: >- + Whether the file was successfully deleted + additionalProperties: false + required: + - id + - object + - deleted + title: OpenAIFileDeleteResponse + description: >- + Response for deleting a file in OpenAI Files API. + Response: + type: object + title: Response + HealthInfo: + type: object + properties: + status: + type: string + enum: + - OK + - Error + - Not Implemented + description: Current health status of the service + additionalProperties: false + required: + - status + title: HealthInfo + description: >- + Health status information for the service. + RouteInfo: + type: object + properties: + route: + type: string + description: The API endpoint path + method: + type: string + description: HTTP method for the route + provider_types: + type: array + items: + type: string + description: >- + List of provider types that implement this route + additionalProperties: false + required: + - route + - method + - provider_types + title: RouteInfo + description: >- + Information about an API route including its path, method, and implementing + providers. + ListRoutesResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/RouteInfo' + description: >- + List of available route information objects + additionalProperties: false + required: + - data + title: ListRoutesResponse + description: >- + Response containing a list of all available API routes. + Model: + type: object + properties: + identifier: + type: string + description: >- + Unique identifier for this resource in llama stack + provider_resource_id: + type: string + description: >- + Unique identifier for this resource in the provider + provider_id: + type: string + description: >- + ID of the provider that owns this resource + type: + type: string + enum: + - model + - shield + - vector_store + - dataset + - scoring_function + - benchmark + - tool + - tool_group + - prompt + const: model + default: model + description: >- + The resource type, always 'model' for model resources + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: Any additional metadata for this model + model_type: + $ref: '#/components/schemas/ModelType' + default: llm + description: >- + The type of model (LLM or embedding model) + additionalProperties: false + required: + - identifier + - provider_id + - type + - metadata + - model_type + title: Model + description: >- + A model resource representing an AI model registered in Llama Stack. + ModelType: + type: string + enum: + - llm + - embedding + title: ModelType + description: >- + Enumeration of supported model types in Llama Stack. + ListModelsResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Model' + additionalProperties: false + required: + - data + title: ListModelsResponse + RegisterModelRequest: + type: object + properties: + model_id: + type: string + description: The identifier of the model to register. + provider_model_id: + type: string + description: >- + The identifier of the model in the provider. + provider_id: + type: string + description: The identifier of the provider. + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: Any additional metadata for this model. + model_type: + $ref: '#/components/schemas/ModelType' + description: The type of model to register. + additionalProperties: false + required: + - model_id + title: RegisterModelRequest + RunModerationRequest: + type: object + properties: + input: + oneOf: + - type: string + - type: array + items: + type: string + description: >- + Input (or inputs) to classify. Can be a single string, an array of strings, + or an array of multi-modal input objects similar to other models. + model: + type: string + description: >- + The content moderation model you would like to use. + additionalProperties: false + required: + - input + - model + title: RunModerationRequest + ModerationObject: + type: object + properties: + id: + type: string + description: >- + The unique identifier for the moderation request. + model: + type: string + description: >- + The model used to generate the moderation results. + results: + type: array + items: + $ref: '#/components/schemas/ModerationObjectResults' + description: A list of moderation objects + additionalProperties: false + required: + - id + - model + - results + title: ModerationObject + description: A moderation object. + ModerationObjectResults: + type: object + properties: + flagged: + type: boolean + description: >- + Whether any of the below categories are flagged. + categories: + type: object + additionalProperties: + type: boolean + description: >- + A list of the categories, and whether they are flagged or not. + category_applied_input_types: + type: object + additionalProperties: + type: array + items: + type: string + description: >- + A list of the categories along with the input type(s) that the score applies + to. + category_scores: + type: object + additionalProperties: + type: number + description: >- + A list of the categories along with their scores as predicted by model. + user_message: + type: string + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + additionalProperties: false + required: + - flagged + - metadata + title: ModerationObjectResults + description: A moderation object. + Prompt: + type: object + properties: + prompt: + type: string + description: >- + The system prompt text with variable placeholders. Variables are only + supported when using the Responses API. + version: + type: integer + description: >- + Version (integer starting at 1, incremented on save) + prompt_id: + type: string + description: >- + Unique identifier formatted as 'pmpt_<48-digit-hash>' + variables: + type: array + items: + type: string + description: >- + List of prompt variable names that can be used in the prompt template + is_default: + type: boolean + default: false + description: >- + Boolean indicating whether this version is the default version for this + prompt + additionalProperties: false + required: + - version + - prompt_id + - variables + - is_default + title: Prompt + description: >- + A prompt resource representing a stored OpenAI Compatible prompt template + in Llama Stack. + ListPromptsResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Prompt' + additionalProperties: false + required: + - data + title: ListPromptsResponse + description: Response model to list prompts. + CreatePromptRequest: + type: object + properties: + prompt: + type: string + description: >- + The prompt text content with variable placeholders. + variables: + type: array + items: + type: string + description: >- + List of variable names that can be used in the prompt template. + additionalProperties: false + required: + - prompt + title: CreatePromptRequest + UpdatePromptRequest: + type: object + properties: + prompt: + type: string + description: The updated prompt text content. + version: + type: integer + description: >- + The current version of the prompt being updated. + variables: + type: array + items: + type: string + description: >- + Updated list of variable names that can be used in the prompt template. + set_as_default: + type: boolean + description: >- + Set the new version as the default (default=True). + additionalProperties: false + required: + - prompt + - version + - set_as_default + title: UpdatePromptRequest + SetDefaultVersionRequest: + type: object + properties: + version: + type: integer + description: The version to set as default. + additionalProperties: false + required: + - version + title: SetDefaultVersionRequest + ProviderInfo: + type: object + properties: + api: + type: string + description: The API name this provider implements + provider_id: + type: string + description: Unique identifier for the provider + provider_type: + type: string + description: The type of provider implementation + config: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + Configuration parameters for the provider + health: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: Current health status of the provider + additionalProperties: false + required: + - api + - provider_id + - provider_type + - config + - health + title: ProviderInfo + description: >- + Information about a registered provider including its configuration and health + status. + ListProvidersResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/ProviderInfo' + description: List of provider information objects + additionalProperties: false + required: + - data + title: ListProvidersResponse + description: >- + Response containing a list of all available providers. + ListOpenAIResponseObject: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/OpenAIResponseObjectWithInput' + description: >- + List of response objects with their input context + has_more: + type: boolean + description: >- + Whether there are more results available beyond this page + first_id: + type: string + description: >- + Identifier of the first item in this page + last_id: + type: string + description: Identifier of the last item in this page + object: + type: string + const: list + default: list + description: Object type identifier, always "list" + additionalProperties: false + required: + - data + - has_more + - first_id + - last_id + - object + title: ListOpenAIResponseObject + description: >- + Paginated list of OpenAI response objects with navigation metadata. + OpenAIResponseError: + type: object + properties: + code: + type: string + description: >- + Error code identifying the type of failure + message: + type: string + description: >- + Human-readable error message describing the failure + additionalProperties: false + required: + - code + - message + title: OpenAIResponseError + description: >- + Error details for failed OpenAI response requests. + OpenAIResponseInput: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseOutputMessageWebSearchToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageFileSearchToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageFunctionToolCall' + - $ref: '#/components/schemas/OpenAIResponseInputFunctionToolCallOutput' + - $ref: '#/components/schemas/OpenAIResponseMCPApprovalRequest' + - $ref: '#/components/schemas/OpenAIResponseMCPApprovalResponse' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageMCPCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageMCPListTools' + - $ref: '#/components/schemas/OpenAIResponseMessage' + OpenAIResponseInputToolFileSearch: + type: object + properties: + type: + type: string + const: file_search + default: file_search + description: >- + Tool type identifier, always "file_search" + vector_store_ids: + type: array + items: + type: string + description: >- + List of vector store identifiers to search within + filters: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Additional filters to apply to the search + max_num_results: + type: integer + default: 10 + description: >- + (Optional) Maximum number of search results to return (1-50) + ranking_options: + type: object + properties: + ranker: + type: string + description: >- + (Optional) Name of the ranking algorithm to use + score_threshold: + type: number + default: 0.0 + description: >- + (Optional) Minimum relevance score threshold for results + additionalProperties: false + description: >- + (Optional) Options for ranking and scoring search results + additionalProperties: false + required: + - type + - vector_store_ids + title: OpenAIResponseInputToolFileSearch + description: >- + File search tool configuration for OpenAI response inputs. + OpenAIResponseInputToolFunction: + type: object + properties: + type: + type: string + const: function + default: function + description: Tool type identifier, always "function" + name: + type: string + description: Name of the function that can be called + description: + type: string + description: >- + (Optional) Description of what the function does + parameters: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) JSON schema defining the function's parameters + strict: + type: boolean + description: >- + (Optional) Whether to enforce strict parameter validation + additionalProperties: false + required: + - type + - name + title: OpenAIResponseInputToolFunction + description: >- + Function tool configuration for OpenAI response inputs. + OpenAIResponseInputToolWebSearch: + type: object + properties: + type: + oneOf: + - type: string + const: web_search + - type: string + const: web_search_preview + - type: string + const: web_search_preview_2025_03_11 + default: web_search + description: Web search tool type variant to use + search_context_size: + type: string + default: medium + description: >- + (Optional) Size of search context, must be "low", "medium", or "high" + additionalProperties: false + required: + - type + title: OpenAIResponseInputToolWebSearch + description: >- + Web search tool configuration for OpenAI response inputs. + OpenAIResponseObjectWithInput: + type: object + properties: + created_at: + type: integer + description: >- + Unix timestamp when the response was created + error: + $ref: '#/components/schemas/OpenAIResponseError' + description: >- + (Optional) Error details if the response generation failed + id: + type: string + description: Unique identifier for this response + model: + type: string + description: Model identifier used for generation + object: + type: string + const: response + default: response + description: >- + Object type identifier, always "response" + output: + type: array + items: + $ref: '#/components/schemas/OpenAIResponseOutput' + description: >- + List of generated output items (messages, tool calls, etc.) + parallel_tool_calls: + type: boolean + default: false + description: >- + Whether tool calls can be executed in parallel + previous_response_id: + type: string + description: >- + (Optional) ID of the previous response in a conversation + status: + type: string + description: >- + Current status of the response generation + temperature: + type: number + description: >- + (Optional) Sampling temperature used for generation + text: + $ref: '#/components/schemas/OpenAIResponseText' + description: >- + Text formatting configuration for the response + top_p: + type: number + description: >- + (Optional) Nucleus sampling parameter used for generation + tools: + type: array + items: + $ref: '#/components/schemas/OpenAIResponseTool' + description: >- + (Optional) An array of tools the model may call while generating a response. + truncation: + type: string + description: >- + (Optional) Truncation strategy applied to the response + usage: + $ref: '#/components/schemas/OpenAIResponseUsage' + description: >- + (Optional) Token usage information for the response + instructions: + type: string + description: >- + (Optional) System message inserted into the model's context + input: + type: array + items: + $ref: '#/components/schemas/OpenAIResponseInput' + description: >- + List of input items that led to this response + additionalProperties: false + required: + - created_at + - id + - model + - object + - output + - parallel_tool_calls + - status + - text + - input + title: OpenAIResponseObjectWithInput + description: >- + OpenAI response object extended with input context information. + OpenAIResponseOutput: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseMessage' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageWebSearchToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageFileSearchToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageFunctionToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageMCPCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageMCPListTools' + - $ref: '#/components/schemas/OpenAIResponseMCPApprovalRequest' + discriminator: + propertyName: type + mapping: + message: '#/components/schemas/OpenAIResponseMessage' + web_search_call: '#/components/schemas/OpenAIResponseOutputMessageWebSearchToolCall' + file_search_call: '#/components/schemas/OpenAIResponseOutputMessageFileSearchToolCall' + function_call: '#/components/schemas/OpenAIResponseOutputMessageFunctionToolCall' + mcp_call: '#/components/schemas/OpenAIResponseOutputMessageMCPCall' + mcp_list_tools: '#/components/schemas/OpenAIResponseOutputMessageMCPListTools' + mcp_approval_request: '#/components/schemas/OpenAIResponseMCPApprovalRequest' + OpenAIResponseText: + type: object + properties: + format: + type: object + properties: + type: + oneOf: + - type: string + const: text + - type: string + const: json_schema + - type: string + const: json_object + description: >- + Must be "text", "json_schema", or "json_object" to identify the format + type + name: + type: string + description: >- + The name of the response format. Only used for json_schema. + schema: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + The JSON schema the response should conform to. In a Python SDK, this + is often a `pydantic` model. Only used for json_schema. + description: + type: string + description: >- + (Optional) A description of the response format. Only used for json_schema. + strict: + type: boolean + description: >- + (Optional) Whether to strictly enforce the JSON schema. If true, the + response must match the schema exactly. Only used for json_schema. + additionalProperties: false + required: + - type + description: >- + (Optional) Text format configuration specifying output format requirements + additionalProperties: false + title: OpenAIResponseText + description: >- + Text response configuration for OpenAI responses. + OpenAIResponseTool: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseInputToolWebSearch' + - $ref: '#/components/schemas/OpenAIResponseInputToolFileSearch' + - $ref: '#/components/schemas/OpenAIResponseInputToolFunction' + - $ref: '#/components/schemas/OpenAIResponseToolMCP' + discriminator: + propertyName: type + mapping: + web_search: '#/components/schemas/OpenAIResponseInputToolWebSearch' + file_search: '#/components/schemas/OpenAIResponseInputToolFileSearch' + function: '#/components/schemas/OpenAIResponseInputToolFunction' + mcp: '#/components/schemas/OpenAIResponseToolMCP' + OpenAIResponseToolMCP: + type: object + properties: + type: + type: string + const: mcp + default: mcp + description: Tool type identifier, always "mcp" + server_label: + type: string + description: Label to identify this MCP server + allowed_tools: + oneOf: + - type: array + items: + type: string + - type: object + properties: + tool_names: + type: array + items: + type: string + description: >- + (Optional) List of specific tool names that are allowed + additionalProperties: false + title: AllowedToolsFilter + description: >- + Filter configuration for restricting which MCP tools can be used. + description: >- + (Optional) Restriction on which tools can be used from this server + additionalProperties: false + required: + - type + - server_label + title: OpenAIResponseToolMCP + description: >- + Model Context Protocol (MCP) tool configuration for OpenAI response object. + OpenAIResponseUsage: + type: object + properties: + input_tokens: + type: integer + description: Number of tokens in the input + output_tokens: + type: integer + description: Number of tokens in the output + total_tokens: + type: integer + description: Total tokens used (input + output) + input_tokens_details: + type: object + properties: + cached_tokens: + type: integer + description: Number of tokens retrieved from cache + additionalProperties: false + description: Detailed breakdown of input token usage + output_tokens_details: + type: object + properties: + reasoning_tokens: + type: integer + description: >- + Number of tokens used for reasoning (o1/o3 models) + additionalProperties: false + description: Detailed breakdown of output token usage + additionalProperties: false + required: + - input_tokens + - output_tokens + - total_tokens + title: OpenAIResponseUsage + description: Usage information for OpenAI response. + ResponseGuardrailSpec: + type: object + properties: + type: + type: string + description: The type/identifier of the guardrail. + additionalProperties: false + required: + - type + title: ResponseGuardrailSpec + description: >- + Specification for a guardrail to apply during response generation. + OpenAIResponseInputTool: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseInputToolWebSearch' + - $ref: '#/components/schemas/OpenAIResponseInputToolFileSearch' + - $ref: '#/components/schemas/OpenAIResponseInputToolFunction' + - $ref: '#/components/schemas/OpenAIResponseInputToolMCP' + discriminator: + propertyName: type + mapping: + web_search: '#/components/schemas/OpenAIResponseInputToolWebSearch' + file_search: '#/components/schemas/OpenAIResponseInputToolFileSearch' + function: '#/components/schemas/OpenAIResponseInputToolFunction' + mcp: '#/components/schemas/OpenAIResponseInputToolMCP' + OpenAIResponseInputToolMCP: + type: object + properties: + type: + type: string + const: mcp + default: mcp + description: Tool type identifier, always "mcp" + server_label: + type: string + description: Label to identify this MCP server + server_url: + type: string + description: URL endpoint of the MCP server + headers: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) HTTP headers to include when connecting to the server + require_approval: + oneOf: + - type: string + const: always + - type: string + const: never + - type: object + properties: + always: + type: array + items: + type: string + description: >- + (Optional) List of tool names that always require approval + never: + type: array + items: + type: string + description: >- + (Optional) List of tool names that never require approval + additionalProperties: false + title: ApprovalFilter + description: >- + Filter configuration for MCP tool approval requirements. + default: never + description: >- + Approval requirement for tool calls ("always", "never", or filter) + allowed_tools: + oneOf: + - type: array + items: + type: string + - type: object + properties: + tool_names: + type: array + items: + type: string + description: >- + (Optional) List of specific tool names that are allowed + additionalProperties: false + title: AllowedToolsFilter + description: >- + Filter configuration for restricting which MCP tools can be used. + description: >- + (Optional) Restriction on which tools can be used from this server + additionalProperties: false + required: + - type + - server_label + - server_url + - require_approval + title: OpenAIResponseInputToolMCP + description: >- + Model Context Protocol (MCP) tool configuration for OpenAI response inputs. + CreateOpenaiResponseRequest: + type: object + properties: + input: + oneOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/OpenAIResponseInput' + description: Input message(s) to create the response. + model: + type: string + description: The underlying LLM used for completions. + instructions: + type: string + previous_response_id: + type: string + description: >- + (Optional) if specified, the new response will be a continuation of the + previous response. This can be used to easily fork-off new responses from + existing responses. + conversation: + type: string + description: >- + (Optional) The ID of a conversation to add the response to. Must begin + with 'conv_'. Input and output messages will be automatically added to + the conversation. + store: + type: boolean + stream: + type: boolean + temperature: + type: number + text: + $ref: '#/components/schemas/OpenAIResponseText' + tools: + type: array + items: + $ref: '#/components/schemas/OpenAIResponseInputTool' + include: + type: array + items: + type: string + description: >- + (Optional) Additional fields to include in the response. + max_infer_iters: + type: integer + additionalProperties: false + required: + - input + - model + title: CreateOpenaiResponseRequest + OpenAIResponseObject: + type: object + properties: + created_at: + type: integer + description: >- + Unix timestamp when the response was created + error: + $ref: '#/components/schemas/OpenAIResponseError' + description: >- + (Optional) Error details if the response generation failed + id: + type: string + description: Unique identifier for this response + model: + type: string + description: Model identifier used for generation + object: + type: string + const: response + default: response + description: >- + Object type identifier, always "response" + output: + type: array + items: + $ref: '#/components/schemas/OpenAIResponseOutput' + description: >- + List of generated output items (messages, tool calls, etc.) + parallel_tool_calls: + type: boolean + default: false + description: >- + Whether tool calls can be executed in parallel + previous_response_id: + type: string + description: >- + (Optional) ID of the previous response in a conversation + status: + type: string + description: >- + Current status of the response generation + temperature: + type: number + description: >- + (Optional) Sampling temperature used for generation + text: + $ref: '#/components/schemas/OpenAIResponseText' + description: >- + Text formatting configuration for the response + top_p: + type: number + description: >- + (Optional) Nucleus sampling parameter used for generation + tools: + type: array + items: + $ref: '#/components/schemas/OpenAIResponseTool' + description: >- + (Optional) An array of tools the model may call while generating a response. + truncation: + type: string + description: >- + (Optional) Truncation strategy applied to the response + usage: + $ref: '#/components/schemas/OpenAIResponseUsage' + description: >- + (Optional) Token usage information for the response + instructions: + type: string + description: >- + (Optional) System message inserted into the model's context + additionalProperties: false + required: + - created_at + - id + - model + - object + - output + - parallel_tool_calls + - status + - text + title: OpenAIResponseObject + description: >- + Complete OpenAI response object containing generation results and metadata. + OpenAIResponseContentPartOutputText: + type: object + properties: + type: + type: string + const: output_text + default: output_text + description: >- + Content part type identifier, always "output_text" + text: + type: string + description: Text emitted for this content part + annotations: + type: array + items: + $ref: '#/components/schemas/OpenAIResponseAnnotations' + description: >- + Structured annotations associated with the text + logprobs: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: (Optional) Token log probability details + additionalProperties: false + required: + - type + - text + - annotations + title: OpenAIResponseContentPartOutputText + description: >- + Text content within a streamed response part. + "OpenAIResponseContentPartReasoningSummary": + type: object + properties: + type: + type: string + const: summary_text + default: summary_text + description: >- + Content part type identifier, always "summary_text" + text: + type: string + description: Summary text + additionalProperties: false + required: + - type + - text + title: >- + OpenAIResponseContentPartReasoningSummary + description: >- + Reasoning summary part in a streamed response. + OpenAIResponseContentPartReasoningText: + type: object + properties: + type: + type: string + const: reasoning_text + default: reasoning_text + description: >- + Content part type identifier, always "reasoning_text" + text: + type: string + description: Reasoning text supplied by the model + additionalProperties: false + required: + - type + - text + title: OpenAIResponseContentPartReasoningText + description: >- + Reasoning text emitted as part of a streamed response. + OpenAIResponseObjectStream: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseCreated' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseInProgress' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseOutputItemAdded' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseOutputItemDone' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseOutputTextDelta' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseOutputTextDone' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseFunctionCallArgumentsDelta' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseFunctionCallArgumentsDone' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseWebSearchCallInProgress' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseWebSearchCallSearching' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseWebSearchCallCompleted' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpListToolsInProgress' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpListToolsFailed' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpListToolsCompleted' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallArgumentsDelta' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallArgumentsDone' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallInProgress' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallFailed' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallCompleted' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseContentPartAdded' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseContentPartDone' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningTextDelta' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningTextDone' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningSummaryPartAdded' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningSummaryPartDone' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningSummaryTextDelta' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningSummaryTextDone' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseRefusalDelta' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseRefusalDone' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseOutputTextAnnotationAdded' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseFileSearchCallInProgress' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseFileSearchCallSearching' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseFileSearchCallCompleted' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseIncomplete' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseFailed' + - $ref: '#/components/schemas/OpenAIResponseObjectStreamResponseCompleted' + discriminator: + propertyName: type + mapping: + response.created: '#/components/schemas/OpenAIResponseObjectStreamResponseCreated' + response.in_progress: '#/components/schemas/OpenAIResponseObjectStreamResponseInProgress' + response.output_item.added: '#/components/schemas/OpenAIResponseObjectStreamResponseOutputItemAdded' + response.output_item.done: '#/components/schemas/OpenAIResponseObjectStreamResponseOutputItemDone' + response.output_text.delta: '#/components/schemas/OpenAIResponseObjectStreamResponseOutputTextDelta' + response.output_text.done: '#/components/schemas/OpenAIResponseObjectStreamResponseOutputTextDone' + response.function_call_arguments.delta: '#/components/schemas/OpenAIResponseObjectStreamResponseFunctionCallArgumentsDelta' + response.function_call_arguments.done: '#/components/schemas/OpenAIResponseObjectStreamResponseFunctionCallArgumentsDone' + response.web_search_call.in_progress: '#/components/schemas/OpenAIResponseObjectStreamResponseWebSearchCallInProgress' + response.web_search_call.searching: '#/components/schemas/OpenAIResponseObjectStreamResponseWebSearchCallSearching' + response.web_search_call.completed: '#/components/schemas/OpenAIResponseObjectStreamResponseWebSearchCallCompleted' + response.mcp_list_tools.in_progress: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpListToolsInProgress' + response.mcp_list_tools.failed: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpListToolsFailed' + response.mcp_list_tools.completed: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpListToolsCompleted' + response.mcp_call.arguments.delta: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallArgumentsDelta' + response.mcp_call.arguments.done: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallArgumentsDone' + response.mcp_call.in_progress: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallInProgress' + response.mcp_call.failed: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallFailed' + response.mcp_call.completed: '#/components/schemas/OpenAIResponseObjectStreamResponseMcpCallCompleted' + response.content_part.added: '#/components/schemas/OpenAIResponseObjectStreamResponseContentPartAdded' + response.content_part.done: '#/components/schemas/OpenAIResponseObjectStreamResponseContentPartDone' + response.reasoning_text.delta: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningTextDelta' + response.reasoning_text.done: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningTextDone' + response.reasoning_summary_part.added: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningSummaryPartAdded' + response.reasoning_summary_part.done: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningSummaryPartDone' + response.reasoning_summary_text.delta: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningSummaryTextDelta' + response.reasoning_summary_text.done: '#/components/schemas/OpenAIResponseObjectStreamResponseReasoningSummaryTextDone' + response.refusal.delta: '#/components/schemas/OpenAIResponseObjectStreamResponseRefusalDelta' + response.refusal.done: '#/components/schemas/OpenAIResponseObjectStreamResponseRefusalDone' + response.output_text.annotation.added: '#/components/schemas/OpenAIResponseObjectStreamResponseOutputTextAnnotationAdded' + response.file_search_call.in_progress: '#/components/schemas/OpenAIResponseObjectStreamResponseFileSearchCallInProgress' + response.file_search_call.searching: '#/components/schemas/OpenAIResponseObjectStreamResponseFileSearchCallSearching' + response.file_search_call.completed: '#/components/schemas/OpenAIResponseObjectStreamResponseFileSearchCallCompleted' + response.incomplete: '#/components/schemas/OpenAIResponseObjectStreamResponseIncomplete' + response.failed: '#/components/schemas/OpenAIResponseObjectStreamResponseFailed' + response.completed: '#/components/schemas/OpenAIResponseObjectStreamResponseCompleted' + "OpenAIResponseObjectStreamResponseCompleted": + type: object + properties: + response: + $ref: '#/components/schemas/OpenAIResponseObject' + description: Completed response object + type: + type: string + const: response.completed + default: response.completed + description: >- + Event type identifier, always "response.completed" + additionalProperties: false + required: + - response + - type + title: >- + OpenAIResponseObjectStreamResponseCompleted + description: >- + Streaming event indicating a response has been completed. + "OpenAIResponseObjectStreamResponseContentPartAdded": + type: object + properties: + content_index: + type: integer + description: >- + Index position of the part within the content array + response_id: + type: string + description: >- + Unique identifier of the response containing this content + item_id: + type: string + description: >- + Unique identifier of the output item containing this content part + output_index: + type: integer + description: >- + Index position of the output item in the response + part: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseContentPartOutputText' + - $ref: '#/components/schemas/OpenAIResponseContentPartRefusal' + - $ref: '#/components/schemas/OpenAIResponseContentPartReasoningText' + discriminator: + propertyName: type + mapping: + output_text: '#/components/schemas/OpenAIResponseContentPartOutputText' + refusal: '#/components/schemas/OpenAIResponseContentPartRefusal' + reasoning_text: '#/components/schemas/OpenAIResponseContentPartReasoningText' + description: The content part that was added + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.content_part.added + default: response.content_part.added + description: >- + Event type identifier, always "response.content_part.added" + additionalProperties: false + required: + - content_index + - response_id + - item_id + - output_index + - part + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseContentPartAdded + description: >- + Streaming event for when a new content part is added to a response item. + "OpenAIResponseObjectStreamResponseContentPartDone": + type: object + properties: + content_index: + type: integer + description: >- + Index position of the part within the content array + response_id: + type: string + description: >- + Unique identifier of the response containing this content + item_id: + type: string + description: >- + Unique identifier of the output item containing this content part + output_index: + type: integer + description: >- + Index position of the output item in the response + part: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseContentPartOutputText' + - $ref: '#/components/schemas/OpenAIResponseContentPartRefusal' + - $ref: '#/components/schemas/OpenAIResponseContentPartReasoningText' + discriminator: + propertyName: type + mapping: + output_text: '#/components/schemas/OpenAIResponseContentPartOutputText' + refusal: '#/components/schemas/OpenAIResponseContentPartRefusal' + reasoning_text: '#/components/schemas/OpenAIResponseContentPartReasoningText' + description: The completed content part + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.content_part.done + default: response.content_part.done + description: >- + Event type identifier, always "response.content_part.done" + additionalProperties: false + required: + - content_index + - response_id + - item_id + - output_index + - part + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseContentPartDone + description: >- + Streaming event for when a content part is completed. + "OpenAIResponseObjectStreamResponseCreated": + type: object + properties: + response: + $ref: '#/components/schemas/OpenAIResponseObject' + description: The response object that was created + type: + type: string + const: response.created + default: response.created + description: >- + Event type identifier, always "response.created" + additionalProperties: false + required: + - response + - type + title: >- + OpenAIResponseObjectStreamResponseCreated + description: >- + Streaming event indicating a new response has been created. + OpenAIResponseObjectStreamResponseFailed: + type: object + properties: + response: + $ref: '#/components/schemas/OpenAIResponseObject' + description: Response object describing the failure + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.failed + default: response.failed + description: >- + Event type identifier, always "response.failed" + additionalProperties: false + required: + - response + - sequence_number + - type + title: OpenAIResponseObjectStreamResponseFailed + description: >- + Streaming event emitted when a response fails. + "OpenAIResponseObjectStreamResponseFileSearchCallCompleted": + type: object + properties: + item_id: + type: string + description: >- + Unique identifier of the completed file search call + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.file_search_call.completed + default: response.file_search_call.completed + description: >- + Event type identifier, always "response.file_search_call.completed" + additionalProperties: false + required: + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseFileSearchCallCompleted + description: >- + Streaming event for completed file search calls. + "OpenAIResponseObjectStreamResponseFileSearchCallInProgress": + type: object + properties: + item_id: + type: string + description: >- + Unique identifier of the file search call + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.file_search_call.in_progress + default: response.file_search_call.in_progress + description: >- + Event type identifier, always "response.file_search_call.in_progress" + additionalProperties: false + required: + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseFileSearchCallInProgress + description: >- + Streaming event for file search calls in progress. + "OpenAIResponseObjectStreamResponseFileSearchCallSearching": + type: object + properties: + item_id: + type: string + description: >- + Unique identifier of the file search call + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.file_search_call.searching + default: response.file_search_call.searching + description: >- + Event type identifier, always "response.file_search_call.searching" + additionalProperties: false + required: + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseFileSearchCallSearching + description: >- + Streaming event for file search currently searching. + "OpenAIResponseObjectStreamResponseFunctionCallArgumentsDelta": + type: object + properties: + delta: + type: string + description: >- + Incremental function call arguments being added + item_id: + type: string + description: >- + Unique identifier of the function call being updated + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.function_call_arguments.delta + default: response.function_call_arguments.delta + description: >- + Event type identifier, always "response.function_call_arguments.delta" + additionalProperties: false + required: + - delta + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseFunctionCallArgumentsDelta + description: >- + Streaming event for incremental function call argument updates. + "OpenAIResponseObjectStreamResponseFunctionCallArgumentsDone": + type: object + properties: + arguments: + type: string + description: >- + Final complete arguments JSON string for the function call + item_id: + type: string + description: >- + Unique identifier of the completed function call + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.function_call_arguments.done + default: response.function_call_arguments.done + description: >- + Event type identifier, always "response.function_call_arguments.done" + additionalProperties: false + required: + - arguments + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseFunctionCallArgumentsDone + description: >- + Streaming event for when function call arguments are completed. + "OpenAIResponseObjectStreamResponseInProgress": + type: object + properties: + response: + $ref: '#/components/schemas/OpenAIResponseObject' + description: Current response state while in progress + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.in_progress + default: response.in_progress + description: >- + Event type identifier, always "response.in_progress" + additionalProperties: false + required: + - response + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseInProgress + description: >- + Streaming event indicating the response remains in progress. + "OpenAIResponseObjectStreamResponseIncomplete": + type: object + properties: + response: + $ref: '#/components/schemas/OpenAIResponseObject' + description: >- + Response object describing the incomplete state + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.incomplete + default: response.incomplete + description: >- + Event type identifier, always "response.incomplete" + additionalProperties: false + required: + - response + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseIncomplete + description: >- + Streaming event emitted when a response ends in an incomplete state. + "OpenAIResponseObjectStreamResponseMcpCallArgumentsDelta": + type: object + properties: + delta: + type: string + item_id: + type: string + output_index: + type: integer + sequence_number: + type: integer + type: + type: string + const: response.mcp_call.arguments.delta + default: response.mcp_call.arguments.delta + additionalProperties: false + required: + - delta + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseMcpCallArgumentsDelta + "OpenAIResponseObjectStreamResponseMcpCallArgumentsDone": + type: object + properties: + arguments: + type: string + item_id: + type: string + output_index: + type: integer + sequence_number: + type: integer + type: + type: string + const: response.mcp_call.arguments.done + default: response.mcp_call.arguments.done + additionalProperties: false + required: + - arguments + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseMcpCallArgumentsDone + "OpenAIResponseObjectStreamResponseMcpCallCompleted": + type: object + properties: + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.mcp_call.completed + default: response.mcp_call.completed + description: >- + Event type identifier, always "response.mcp_call.completed" + additionalProperties: false + required: + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseMcpCallCompleted + description: Streaming event for completed MCP calls. + "OpenAIResponseObjectStreamResponseMcpCallFailed": + type: object + properties: + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.mcp_call.failed + default: response.mcp_call.failed + description: >- + Event type identifier, always "response.mcp_call.failed" + additionalProperties: false + required: + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseMcpCallFailed + description: Streaming event for failed MCP calls. + "OpenAIResponseObjectStreamResponseMcpCallInProgress": + type: object + properties: + item_id: + type: string + description: Unique identifier of the MCP call + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.mcp_call.in_progress + default: response.mcp_call.in_progress + description: >- + Event type identifier, always "response.mcp_call.in_progress" + additionalProperties: false + required: + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseMcpCallInProgress + description: >- + Streaming event for MCP calls in progress. + "OpenAIResponseObjectStreamResponseMcpListToolsCompleted": + type: object + properties: + sequence_number: + type: integer + type: + type: string + const: response.mcp_list_tools.completed + default: response.mcp_list_tools.completed + additionalProperties: false + required: + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseMcpListToolsCompleted + "OpenAIResponseObjectStreamResponseMcpListToolsFailed": + type: object + properties: + sequence_number: + type: integer + type: + type: string + const: response.mcp_list_tools.failed + default: response.mcp_list_tools.failed + additionalProperties: false + required: + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseMcpListToolsFailed + "OpenAIResponseObjectStreamResponseMcpListToolsInProgress": + type: object + properties: + sequence_number: + type: integer + type: + type: string + const: response.mcp_list_tools.in_progress + default: response.mcp_list_tools.in_progress + additionalProperties: false + required: + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseMcpListToolsInProgress + "OpenAIResponseObjectStreamResponseOutputItemAdded": + type: object + properties: + response_id: + type: string + description: >- + Unique identifier of the response containing this output + item: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseMessage' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageWebSearchToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageFileSearchToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageFunctionToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageMCPCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageMCPListTools' + - $ref: '#/components/schemas/OpenAIResponseMCPApprovalRequest' + discriminator: + propertyName: type + mapping: + message: '#/components/schemas/OpenAIResponseMessage' + web_search_call: '#/components/schemas/OpenAIResponseOutputMessageWebSearchToolCall' + file_search_call: '#/components/schemas/OpenAIResponseOutputMessageFileSearchToolCall' + function_call: '#/components/schemas/OpenAIResponseOutputMessageFunctionToolCall' + mcp_call: '#/components/schemas/OpenAIResponseOutputMessageMCPCall' + mcp_list_tools: '#/components/schemas/OpenAIResponseOutputMessageMCPListTools' + mcp_approval_request: '#/components/schemas/OpenAIResponseMCPApprovalRequest' + description: >- + The output item that was added (message, tool call, etc.) + output_index: + type: integer + description: >- + Index position of this item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.output_item.added + default: response.output_item.added + description: >- + Event type identifier, always "response.output_item.added" + additionalProperties: false + required: + - response_id + - item + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseOutputItemAdded + description: >- + Streaming event for when a new output item is added to the response. + "OpenAIResponseObjectStreamResponseOutputItemDone": + type: object + properties: + response_id: + type: string + description: >- + Unique identifier of the response containing this output + item: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseMessage' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageWebSearchToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageFileSearchToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageFunctionToolCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageMCPCall' + - $ref: '#/components/schemas/OpenAIResponseOutputMessageMCPListTools' + - $ref: '#/components/schemas/OpenAIResponseMCPApprovalRequest' + discriminator: + propertyName: type + mapping: + message: '#/components/schemas/OpenAIResponseMessage' + web_search_call: '#/components/schemas/OpenAIResponseOutputMessageWebSearchToolCall' + file_search_call: '#/components/schemas/OpenAIResponseOutputMessageFileSearchToolCall' + function_call: '#/components/schemas/OpenAIResponseOutputMessageFunctionToolCall' + mcp_call: '#/components/schemas/OpenAIResponseOutputMessageMCPCall' + mcp_list_tools: '#/components/schemas/OpenAIResponseOutputMessageMCPListTools' + mcp_approval_request: '#/components/schemas/OpenAIResponseMCPApprovalRequest' + description: >- + The completed output item (message, tool call, etc.) + output_index: + type: integer + description: >- + Index position of this item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.output_item.done + default: response.output_item.done + description: >- + Event type identifier, always "response.output_item.done" + additionalProperties: false + required: + - response_id + - item + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseOutputItemDone + description: >- + Streaming event for when an output item is completed. + "OpenAIResponseObjectStreamResponseOutputTextAnnotationAdded": + type: object + properties: + item_id: + type: string + description: >- + Unique identifier of the item to which the annotation is being added + output_index: + type: integer + description: >- + Index position of the output item in the response's output array + content_index: + type: integer + description: >- + Index position of the content part within the output item + annotation_index: + type: integer + description: >- + Index of the annotation within the content part + annotation: + oneOf: + - $ref: '#/components/schemas/OpenAIResponseAnnotationFileCitation' + - $ref: '#/components/schemas/OpenAIResponseAnnotationCitation' + - $ref: '#/components/schemas/OpenAIResponseAnnotationContainerFileCitation' + - $ref: '#/components/schemas/OpenAIResponseAnnotationFilePath' + discriminator: + propertyName: type + mapping: + file_citation: '#/components/schemas/OpenAIResponseAnnotationFileCitation' + url_citation: '#/components/schemas/OpenAIResponseAnnotationCitation' + container_file_citation: '#/components/schemas/OpenAIResponseAnnotationContainerFileCitation' + file_path: '#/components/schemas/OpenAIResponseAnnotationFilePath' + description: The annotation object being added + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.output_text.annotation.added + default: response.output_text.annotation.added + description: >- + Event type identifier, always "response.output_text.annotation.added" + additionalProperties: false + required: + - item_id + - output_index + - content_index + - annotation_index + - annotation + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseOutputTextAnnotationAdded + description: >- + Streaming event for when an annotation is added to output text. + "OpenAIResponseObjectStreamResponseOutputTextDelta": + type: object + properties: + content_index: + type: integer + description: Index position within the text content + delta: + type: string + description: Incremental text content being added + item_id: + type: string + description: >- + Unique identifier of the output item being updated + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.output_text.delta + default: response.output_text.delta + description: >- + Event type identifier, always "response.output_text.delta" + additionalProperties: false + required: + - content_index + - delta + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseOutputTextDelta + description: >- + Streaming event for incremental text content updates. + "OpenAIResponseObjectStreamResponseOutputTextDone": + type: object + properties: + content_index: + type: integer + description: Index position within the text content + text: + type: string + description: >- + Final complete text content of the output item + item_id: + type: string + description: >- + Unique identifier of the completed output item + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.output_text.done + default: response.output_text.done + description: >- + Event type identifier, always "response.output_text.done" + additionalProperties: false + required: + - content_index + - text + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseOutputTextDone + description: >- + Streaming event for when text output is completed. + "OpenAIResponseObjectStreamResponseReasoningSummaryPartAdded": + type: object + properties: + item_id: + type: string + description: Unique identifier of the output item + output_index: + type: integer + description: Index position of the output item + part: + $ref: '#/components/schemas/OpenAIResponseContentPartReasoningSummary' + description: The summary part that was added + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + summary_index: + type: integer + description: >- + Index of the summary part within the reasoning summary + type: + type: string + const: response.reasoning_summary_part.added + default: response.reasoning_summary_part.added + description: >- + Event type identifier, always "response.reasoning_summary_part.added" + additionalProperties: false + required: + - item_id + - output_index + - part + - sequence_number + - summary_index + - type + title: >- + OpenAIResponseObjectStreamResponseReasoningSummaryPartAdded + description: >- + Streaming event for when a new reasoning summary part is added. + "OpenAIResponseObjectStreamResponseReasoningSummaryPartDone": + type: object + properties: + item_id: + type: string + description: Unique identifier of the output item + output_index: + type: integer + description: Index position of the output item + part: + $ref: '#/components/schemas/OpenAIResponseContentPartReasoningSummary' + description: The completed summary part + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + summary_index: + type: integer + description: >- + Index of the summary part within the reasoning summary + type: + type: string + const: response.reasoning_summary_part.done + default: response.reasoning_summary_part.done + description: >- + Event type identifier, always "response.reasoning_summary_part.done" + additionalProperties: false + required: + - item_id + - output_index + - part + - sequence_number + - summary_index + - type + title: >- + OpenAIResponseObjectStreamResponseReasoningSummaryPartDone + description: >- + Streaming event for when a reasoning summary part is completed. + "OpenAIResponseObjectStreamResponseReasoningSummaryTextDelta": + type: object + properties: + delta: + type: string + description: Incremental summary text being added + item_id: + type: string + description: Unique identifier of the output item + output_index: + type: integer + description: Index position of the output item + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + summary_index: + type: integer + description: >- + Index of the summary part within the reasoning summary + type: + type: string + const: response.reasoning_summary_text.delta + default: response.reasoning_summary_text.delta + description: >- + Event type identifier, always "response.reasoning_summary_text.delta" + additionalProperties: false + required: + - delta + - item_id + - output_index + - sequence_number + - summary_index + - type + title: >- + OpenAIResponseObjectStreamResponseReasoningSummaryTextDelta + description: >- + Streaming event for incremental reasoning summary text updates. + "OpenAIResponseObjectStreamResponseReasoningSummaryTextDone": + type: object + properties: + text: + type: string + description: Final complete summary text + item_id: + type: string + description: Unique identifier of the output item + output_index: + type: integer + description: Index position of the output item + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + summary_index: + type: integer + description: >- + Index of the summary part within the reasoning summary + type: + type: string + const: response.reasoning_summary_text.done + default: response.reasoning_summary_text.done + description: >- + Event type identifier, always "response.reasoning_summary_text.done" + additionalProperties: false + required: + - text + - item_id + - output_index + - sequence_number + - summary_index + - type + title: >- + OpenAIResponseObjectStreamResponseReasoningSummaryTextDone + description: >- + Streaming event for when reasoning summary text is completed. + "OpenAIResponseObjectStreamResponseReasoningTextDelta": + type: object + properties: + content_index: + type: integer + description: >- + Index position of the reasoning content part + delta: + type: string + description: Incremental reasoning text being added + item_id: + type: string + description: >- + Unique identifier of the output item being updated + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.reasoning_text.delta + default: response.reasoning_text.delta + description: >- + Event type identifier, always "response.reasoning_text.delta" + additionalProperties: false + required: + - content_index + - delta + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseReasoningTextDelta + description: >- + Streaming event for incremental reasoning text updates. + "OpenAIResponseObjectStreamResponseReasoningTextDone": + type: object + properties: + content_index: + type: integer + description: >- + Index position of the reasoning content part + text: + type: string + description: Final complete reasoning text + item_id: + type: string + description: >- + Unique identifier of the completed output item + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.reasoning_text.done + default: response.reasoning_text.done + description: >- + Event type identifier, always "response.reasoning_text.done" + additionalProperties: false + required: + - content_index + - text + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseReasoningTextDone + description: >- + Streaming event for when reasoning text is completed. + "OpenAIResponseObjectStreamResponseRefusalDelta": + type: object + properties: + content_index: + type: integer + description: Index position of the content part + delta: + type: string + description: Incremental refusal text being added + item_id: + type: string + description: Unique identifier of the output item + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.refusal.delta + default: response.refusal.delta + description: >- + Event type identifier, always "response.refusal.delta" + additionalProperties: false + required: + - content_index + - delta + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseRefusalDelta + description: >- + Streaming event for incremental refusal text updates. + "OpenAIResponseObjectStreamResponseRefusalDone": + type: object + properties: + content_index: + type: integer + description: Index position of the content part + refusal: + type: string + description: Final complete refusal text + item_id: + type: string + description: Unique identifier of the output item + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.refusal.done + default: response.refusal.done + description: >- + Event type identifier, always "response.refusal.done" + additionalProperties: false + required: + - content_index + - refusal + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseRefusalDone + description: >- + Streaming event for when refusal text is completed. + "OpenAIResponseObjectStreamResponseWebSearchCallCompleted": + type: object + properties: + item_id: + type: string + description: >- + Unique identifier of the completed web search call + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.web_search_call.completed + default: response.web_search_call.completed + description: >- + Event type identifier, always "response.web_search_call.completed" + additionalProperties: false + required: + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseWebSearchCallCompleted + description: >- + Streaming event for completed web search calls. + "OpenAIResponseObjectStreamResponseWebSearchCallInProgress": + type: object + properties: + item_id: + type: string + description: Unique identifier of the web search call + output_index: + type: integer + description: >- + Index position of the item in the output list + sequence_number: + type: integer + description: >- + Sequential number for ordering streaming events + type: + type: string + const: response.web_search_call.in_progress + default: response.web_search_call.in_progress + description: >- + Event type identifier, always "response.web_search_call.in_progress" + additionalProperties: false + required: + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseWebSearchCallInProgress + description: >- + Streaming event for web search calls in progress. + "OpenAIResponseObjectStreamResponseWebSearchCallSearching": + type: object + properties: + item_id: + type: string + output_index: + type: integer + sequence_number: + type: integer + type: + type: string + const: response.web_search_call.searching + default: response.web_search_call.searching + additionalProperties: false + required: + - item_id + - output_index + - sequence_number + - type + title: >- + OpenAIResponseObjectStreamResponseWebSearchCallSearching + OpenAIDeleteResponseObject: + type: object + properties: + id: + type: string + description: >- + Unique identifier of the deleted response + object: + type: string + const: response + default: response + description: >- + Object type identifier, always "response" + deleted: + type: boolean + default: true + description: Deletion confirmation flag, always True + additionalProperties: false + required: + - id + - object + - deleted + title: OpenAIDeleteResponseObject + description: >- + Response object confirming deletion of an OpenAI response. + ListOpenAIResponseInputItem: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/OpenAIResponseInput' + description: List of input items + object: + type: string + const: list + default: list + description: Object type identifier, always "list" + additionalProperties: false + required: + - data + - object + title: ListOpenAIResponseInputItem + description: >- + List container for OpenAI response input items. + RunShieldRequest: + type: object + properties: + shield_id: + type: string + description: The identifier of the shield to run. + messages: + type: array + items: + $ref: '#/components/schemas/OpenAIMessageParam' + description: The messages to run the shield on. + params: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The parameters of the shield. + additionalProperties: false + required: + - shield_id + - messages + - params + title: RunShieldRequest + RunShieldResponse: + type: object + properties: + violation: + $ref: '#/components/schemas/SafetyViolation' + description: >- + (Optional) Safety violation detected by the shield, if any + additionalProperties: false + title: RunShieldResponse + description: Response from running a safety shield. + SafetyViolation: + type: object + properties: + violation_level: + $ref: '#/components/schemas/ViolationLevel' + description: Severity level of the violation + user_message: + type: string + description: >- + (Optional) Message to convey to the user about the violation + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + Additional metadata including specific violation codes for debugging and + telemetry + additionalProperties: false + required: + - violation_level + - metadata + title: SafetyViolation + description: >- + Details of a safety violation detected by content moderation. + ViolationLevel: + type: string + enum: + - info + - warn + - error + title: ViolationLevel + description: Severity level of a safety violation. + AgentTurnInputType: + type: object + properties: + type: + type: string + const: agent_turn_input + default: agent_turn_input + description: >- + Discriminator type. Always "agent_turn_input" + additionalProperties: false + required: + - type + title: AgentTurnInputType + description: Parameter type for agent turn input. + AggregationFunctionType: + type: string + enum: + - average + - weighted_average + - median + - categorical_count + - accuracy + title: AggregationFunctionType + description: >- + Types of aggregation functions for scoring results. + ArrayType: + type: object + properties: + type: + type: string + const: array + default: array + description: Discriminator type. Always "array" + additionalProperties: false + required: + - type + title: ArrayType + description: Parameter type for array values. + BasicScoringFnParams: + type: object + properties: + type: + $ref: '#/components/schemas/ScoringFnParamsType' + const: basic + default: basic + description: >- + The type of scoring function parameters, always basic + aggregation_functions: + type: array + items: + $ref: '#/components/schemas/AggregationFunctionType' + description: >- + Aggregation functions to apply to the scores of each row + additionalProperties: false + required: + - type + - aggregation_functions + title: BasicScoringFnParams + description: >- + Parameters for basic scoring function configuration. + BooleanType: + type: object + properties: + type: + type: string + const: boolean + default: boolean + description: Discriminator type. Always "boolean" + additionalProperties: false + required: + - type + title: BooleanType + description: Parameter type for boolean values. + ChatCompletionInputType: + type: object + properties: + type: + type: string + const: chat_completion_input + default: chat_completion_input + description: >- + Discriminator type. Always "chat_completion_input" + additionalProperties: false + required: + - type + title: ChatCompletionInputType + description: >- + Parameter type for chat completion input. + CompletionInputType: + type: object + properties: + type: + type: string + const: completion_input + default: completion_input + description: >- + Discriminator type. Always "completion_input" + additionalProperties: false + required: + - type + title: CompletionInputType + description: Parameter type for completion input. + JsonType: + type: object + properties: + type: + type: string + const: json + default: json + description: Discriminator type. Always "json" + additionalProperties: false + required: + - type + title: JsonType + description: Parameter type for JSON values. + LLMAsJudgeScoringFnParams: + type: object + properties: + type: + $ref: '#/components/schemas/ScoringFnParamsType' + const: llm_as_judge + default: llm_as_judge + description: >- + The type of scoring function parameters, always llm_as_judge + judge_model: + type: string + description: >- + Identifier of the LLM model to use as a judge for scoring + prompt_template: + type: string + description: >- + (Optional) Custom prompt template for the judge model + judge_score_regexes: + type: array + items: + type: string + description: >- + Regexes to extract the answer from generated response + aggregation_functions: + type: array + items: + $ref: '#/components/schemas/AggregationFunctionType' + description: >- + Aggregation functions to apply to the scores of each row + additionalProperties: false + required: + - type + - judge_model + - judge_score_regexes + - aggregation_functions + title: LLMAsJudgeScoringFnParams + description: >- + Parameters for LLM-as-judge scoring function configuration. + NumberType: + type: object + properties: + type: + type: string + const: number + default: number + description: Discriminator type. Always "number" + additionalProperties: false + required: + - type + title: NumberType + description: Parameter type for numeric values. + ObjectType: + type: object + properties: + type: + type: string + const: object + default: object + description: Discriminator type. Always "object" + additionalProperties: false + required: + - type + title: ObjectType + description: Parameter type for object values. + RegexParserScoringFnParams: + type: object + properties: + type: + $ref: '#/components/schemas/ScoringFnParamsType' + const: regex_parser + default: regex_parser + description: >- + The type of scoring function parameters, always regex_parser + parsing_regexes: + type: array + items: + type: string + description: >- + Regex to extract the answer from generated response + aggregation_functions: + type: array + items: + $ref: '#/components/schemas/AggregationFunctionType' + description: >- + Aggregation functions to apply to the scores of each row + additionalProperties: false + required: + - type + - parsing_regexes + - aggregation_functions + title: RegexParserScoringFnParams + description: >- + Parameters for regex parser scoring function configuration. + ScoringFn: + type: object + properties: + identifier: + type: string + provider_resource_id: + type: string + provider_id: + type: string + type: + type: string + enum: + - model + - shield + - vector_store + - dataset + - scoring_function + - benchmark + - tool + - tool_group + - prompt + const: scoring_function + default: scoring_function + description: >- + The resource type, always scoring_function + description: + type: string + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + return_type: + oneOf: + - $ref: '#/components/schemas/StringType' + - $ref: '#/components/schemas/NumberType' + - $ref: '#/components/schemas/BooleanType' + - $ref: '#/components/schemas/ArrayType' + - $ref: '#/components/schemas/ObjectType' + - $ref: '#/components/schemas/JsonType' + - $ref: '#/components/schemas/UnionType' + - $ref: '#/components/schemas/ChatCompletionInputType' + - $ref: '#/components/schemas/CompletionInputType' + - $ref: '#/components/schemas/AgentTurnInputType' + discriminator: + propertyName: type + mapping: + string: '#/components/schemas/StringType' + number: '#/components/schemas/NumberType' + boolean: '#/components/schemas/BooleanType' + array: '#/components/schemas/ArrayType' + object: '#/components/schemas/ObjectType' + json: '#/components/schemas/JsonType' + union: '#/components/schemas/UnionType' + chat_completion_input: '#/components/schemas/ChatCompletionInputType' + completion_input: '#/components/schemas/CompletionInputType' + agent_turn_input: '#/components/schemas/AgentTurnInputType' + params: + $ref: '#/components/schemas/ScoringFnParams' + additionalProperties: false + required: + - identifier + - provider_id + - type + - metadata + - return_type + title: ScoringFn + description: >- + A scoring function resource for evaluating model outputs. + ScoringFnParams: + oneOf: + - $ref: '#/components/schemas/LLMAsJudgeScoringFnParams' + - $ref: '#/components/schemas/RegexParserScoringFnParams' + - $ref: '#/components/schemas/BasicScoringFnParams' + discriminator: + propertyName: type + mapping: + llm_as_judge: '#/components/schemas/LLMAsJudgeScoringFnParams' + regex_parser: '#/components/schemas/RegexParserScoringFnParams' + basic: '#/components/schemas/BasicScoringFnParams' + ScoringFnParamsType: + type: string + enum: + - llm_as_judge + - regex_parser + - basic + title: ScoringFnParamsType + description: >- + Types of scoring function parameter configurations. + StringType: + type: object + properties: + type: + type: string + const: string + default: string + description: Discriminator type. Always "string" + additionalProperties: false + required: + - type + title: StringType + description: Parameter type for string values. + UnionType: + type: object + properties: + type: + type: string + const: union + default: union + description: Discriminator type. Always "union" + additionalProperties: false + required: + - type + title: UnionType + description: Parameter type for union values. + ListScoringFunctionsResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/ScoringFn' + additionalProperties: false + required: + - data + title: ListScoringFunctionsResponse + ParamType: + oneOf: + - $ref: '#/components/schemas/StringType' + - $ref: '#/components/schemas/NumberType' + - $ref: '#/components/schemas/BooleanType' + - $ref: '#/components/schemas/ArrayType' + - $ref: '#/components/schemas/ObjectType' + - $ref: '#/components/schemas/JsonType' + - $ref: '#/components/schemas/UnionType' + - $ref: '#/components/schemas/ChatCompletionInputType' + - $ref: '#/components/schemas/CompletionInputType' + - $ref: '#/components/schemas/AgentTurnInputType' + discriminator: + propertyName: type + mapping: + string: '#/components/schemas/StringType' + number: '#/components/schemas/NumberType' + boolean: '#/components/schemas/BooleanType' + array: '#/components/schemas/ArrayType' + object: '#/components/schemas/ObjectType' + json: '#/components/schemas/JsonType' + union: '#/components/schemas/UnionType' + chat_completion_input: '#/components/schemas/ChatCompletionInputType' + completion_input: '#/components/schemas/CompletionInputType' + agent_turn_input: '#/components/schemas/AgentTurnInputType' + RegisterScoringFunctionRequest: + type: object + properties: + scoring_fn_id: + type: string + description: >- + The ID of the scoring function to register. + description: + type: string + description: The description of the scoring function. + return_type: + $ref: '#/components/schemas/ParamType' + description: The return type of the scoring function. + provider_scoring_fn_id: + type: string + description: >- + The ID of the provider scoring function to use for the scoring function. + provider_id: + type: string + description: >- + The ID of the provider to use for the scoring function. + params: + $ref: '#/components/schemas/ScoringFnParams' + description: >- + The parameters for the scoring function for benchmark eval, these can + be overridden for app eval. + additionalProperties: false + required: + - scoring_fn_id + - description + - return_type + title: RegisterScoringFunctionRequest + ScoreRequest: + type: object + properties: + input_rows: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The rows to score. + scoring_functions: + type: object + additionalProperties: + oneOf: + - $ref: '#/components/schemas/ScoringFnParams' + - type: 'null' + description: >- + The scoring functions to use for the scoring. + additionalProperties: false + required: + - input_rows + - scoring_functions + title: ScoreRequest + ScoreResponse: + type: object + properties: + results: + type: object + additionalProperties: + $ref: '#/components/schemas/ScoringResult' + description: >- + A map of scoring function name to ScoringResult. + additionalProperties: false + required: + - results + title: ScoreResponse + description: The response from scoring. + ScoringResult: + type: object + properties: + score_rows: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + The scoring result for each row. Each row is a map of column name to value. + aggregated_results: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: Map of metric name to aggregated value + additionalProperties: false + required: + - score_rows + - aggregated_results + title: ScoringResult + description: A scoring result for a single row. + ScoreBatchRequest: + type: object + properties: + dataset_id: + type: string + description: The ID of the dataset to score. + scoring_functions: + type: object + additionalProperties: + oneOf: + - $ref: '#/components/schemas/ScoringFnParams' + - type: 'null' + description: >- + The scoring functions to use for the scoring. + save_results_dataset: + type: boolean + description: >- + Whether to save the results to a dataset. + additionalProperties: false + required: + - dataset_id + - scoring_functions + - save_results_dataset + title: ScoreBatchRequest + ScoreBatchResponse: + type: object + properties: + dataset_id: + type: string + description: >- + (Optional) The identifier of the dataset that was scored + results: + type: object + additionalProperties: + $ref: '#/components/schemas/ScoringResult' + description: >- + A map of scoring function name to ScoringResult + additionalProperties: false + required: + - results + title: ScoreBatchResponse + description: >- + Response from batch scoring operations on datasets. + Shield: + type: object + properties: + identifier: + type: string + provider_resource_id: + type: string + provider_id: + type: string + type: + type: string + enum: + - model + - shield + - vector_store + - dataset + - scoring_function + - benchmark + - tool + - tool_group + - prompt + const: shield + default: shield + description: The resource type, always shield + params: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Configuration parameters for the shield + additionalProperties: false + required: + - identifier + - provider_id + - type + title: Shield + description: >- + A safety shield resource that can be used to check content. + ListShieldsResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Shield' + additionalProperties: false + required: + - data + title: ListShieldsResponse + RegisterShieldRequest: + type: object + properties: + shield_id: + type: string + description: >- + The identifier of the shield to register. + provider_shield_id: + type: string + description: >- + The identifier of the shield in the provider. + provider_id: + type: string + description: The identifier of the provider. + params: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The parameters of the shield. + additionalProperties: false + required: + - shield_id + title: RegisterShieldRequest + CompletionMessage: + type: object + properties: + role: + type: string + const: assistant + default: assistant + description: >- + Must be "assistant" to identify this as the model's response + content: + $ref: '#/components/schemas/InterleavedContent' + description: The content of the model's response + stop_reason: + type: string + enum: + - end_of_turn + - end_of_message + - out_of_tokens + description: >- + Reason why the model stopped generating. Options are: - `StopReason.end_of_turn`: + The model finished generating the entire response. - `StopReason.end_of_message`: + The model finished generating but generated a partial response -- usually, + a tool call. The user may call the tool and continue the conversation + with the tool's response. - `StopReason.out_of_tokens`: The model ran + out of token budget. + tool_calls: + type: array + items: + $ref: '#/components/schemas/ToolCall' + description: >- + List of tool calls. Each tool call is a ToolCall object. + additionalProperties: false + required: + - role + - content + - stop_reason + title: CompletionMessage + description: >- + A message containing the model's (assistant) response in a chat conversation. + ImageContentItem: + type: object + properties: + type: + type: string + const: image + default: image + description: >- + Discriminator type of the content item. Always "image" + image: + type: object + properties: + url: + $ref: '#/components/schemas/URL' + description: >- + A URL of the image or data URL in the format of data:image/{type};base64,{data}. + Note that URL could have length limits. + data: + type: string + contentEncoding: base64 + description: base64 encoded image data as string + additionalProperties: false + description: >- + Image as a base64 encoded string or an URL + additionalProperties: false + required: + - type + - image + title: ImageContentItem + description: A image content item + InterleavedContent: + oneOf: + - type: string + - $ref: '#/components/schemas/InterleavedContentItem' + - type: array + items: + $ref: '#/components/schemas/InterleavedContentItem' + InterleavedContentItem: + oneOf: + - $ref: '#/components/schemas/ImageContentItem' + - $ref: '#/components/schemas/TextContentItem' + discriminator: + propertyName: type + mapping: + image: '#/components/schemas/ImageContentItem' + text: '#/components/schemas/TextContentItem' + Message: + oneOf: + - $ref: '#/components/schemas/UserMessage' + - $ref: '#/components/schemas/SystemMessage' + - $ref: '#/components/schemas/ToolResponseMessage' + - $ref: '#/components/schemas/CompletionMessage' + discriminator: + propertyName: role + mapping: + user: '#/components/schemas/UserMessage' + system: '#/components/schemas/SystemMessage' + tool: '#/components/schemas/ToolResponseMessage' + assistant: '#/components/schemas/CompletionMessage' + SystemMessage: + type: object + properties: + role: + type: string + const: system + default: system + description: >- + Must be "system" to identify this as a system message + content: + $ref: '#/components/schemas/InterleavedContent' + description: >- + The content of the "system prompt". If multiple system messages are provided, + they are concatenated. The underlying Llama Stack code may also add other + system messages (for example, for formatting tool definitions). + additionalProperties: false + required: + - role + - content + title: SystemMessage + description: >- + A system message providing instructions or context to the model. + TextContentItem: + type: object + properties: + type: + type: string + const: text + default: text + description: >- + Discriminator type of the content item. Always "text" + text: + type: string + description: Text content + additionalProperties: false + required: + - type + - text + title: TextContentItem + description: A text content item + ToolCall: + type: object + properties: + call_id: + type: string + tool_name: + oneOf: + - type: string + enum: + - brave_search + - wolfram_alpha + - photogen + - code_interpreter + title: BuiltinTool + - type: string + arguments: + type: string + additionalProperties: false + required: + - call_id + - tool_name + - arguments + title: ToolCall + ToolResponseMessage: + type: object + properties: + role: + type: string + const: tool + default: tool + description: >- + Must be "tool" to identify this as a tool response + call_id: + type: string + description: >- + Unique identifier for the tool call this response is for + content: + $ref: '#/components/schemas/InterleavedContent' + description: The response content from the tool + additionalProperties: false + required: + - role + - call_id + - content + title: ToolResponseMessage + description: >- + A message representing the result of a tool invocation. + URL: + type: object + properties: + uri: + type: string + description: The URL string pointing to the resource + additionalProperties: false + required: + - uri + title: URL + description: A URL reference to external content. + UserMessage: + type: object + properties: + role: + type: string + const: user + default: user + description: >- + Must be "user" to identify this as a user message + content: + $ref: '#/components/schemas/InterleavedContent' + description: >- + The content of the message, which can include text and other media + context: + $ref: '#/components/schemas/InterleavedContent' + description: >- + (Optional) This field is used internally by Llama Stack to pass RAG context. + This field may be removed in the API in the future. + additionalProperties: false + required: + - role + - content + title: UserMessage + description: >- + A message from the user in a chat conversation. + SyntheticDataGenerateRequest: + type: object + properties: + dialogs: + type: array + items: + $ref: '#/components/schemas/Message' + description: >- + List of conversation messages to use as input for synthetic data generation + filtering_function: + type: string + enum: + - none + - random + - top_k + - top_p + - top_k_top_p + - sigmoid + description: >- + Type of filtering to apply to generated synthetic data samples + model: + type: string + description: >- + (Optional) The identifier of the model to use. The model must be registered + with Llama Stack and available via the /models endpoint + additionalProperties: false + required: + - dialogs + - filtering_function + title: SyntheticDataGenerateRequest + SyntheticDataGenerationResponse: + type: object + properties: + synthetic_data: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + List of generated synthetic data samples that passed the filtering criteria + statistics: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Statistical information about the generation process and filtering + results + additionalProperties: false + required: + - synthetic_data + title: SyntheticDataGenerationResponse + description: >- + Response from the synthetic data generation. Batch of (prompt, response, score) + tuples that pass the threshold. + InvokeToolRequest: + type: object + properties: + tool_name: + type: string + description: The name of the tool to invoke. + kwargs: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + A dictionary of arguments to pass to the tool. + additionalProperties: false + required: + - tool_name + - kwargs + title: InvokeToolRequest + ToolInvocationResult: + type: object + properties: + content: + $ref: '#/components/schemas/InterleavedContent' + description: >- + (Optional) The output content from the tool execution + error_message: + type: string + description: >- + (Optional) Error message if the tool execution failed + error_code: + type: integer + description: >- + (Optional) Numeric error code if the tool execution failed + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Additional metadata about the tool execution + additionalProperties: false + title: ToolInvocationResult + description: Result of a tool invocation. + ToolDef: + type: object + properties: + toolgroup_id: + type: string + description: >- + (Optional) ID of the tool group this tool belongs to + name: + type: string + description: Name of the tool + description: + type: string + description: >- + (Optional) Human-readable description of what the tool does + input_schema: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) JSON Schema for tool inputs (MCP inputSchema) + output_schema: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) JSON Schema for tool outputs (MCP outputSchema) + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Additional metadata about the tool + additionalProperties: false + required: + - name + title: ToolDef + description: >- + Tool definition used in runtime contexts. + ListToolDefsResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/ToolDef' + description: List of tool definitions + additionalProperties: false + required: + - data + title: ListToolDefsResponse + description: >- + Response containing a list of tool definitions. + RAGDocument: + type: object + properties: + document_id: + type: string + description: The unique identifier for the document. + content: + oneOf: + - type: string + - $ref: '#/components/schemas/InterleavedContentItem' + - type: array + items: + $ref: '#/components/schemas/InterleavedContentItem' + - $ref: '#/components/schemas/URL' + description: The content of the document. + mime_type: + type: string + description: The MIME type of the document. + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: Additional metadata for the document. + additionalProperties: false + required: + - document_id + - content + - metadata + title: RAGDocument + description: >- + A document to be used for document ingestion in the RAG Tool. + InsertRequest: + type: object + properties: + documents: + type: array + items: + $ref: '#/components/schemas/RAGDocument' + description: >- + List of documents to index in the RAG system + vector_db_id: + type: string + description: >- + ID of the vector database to store the document embeddings + chunk_size_in_tokens: + type: integer + description: >- + (Optional) Size in tokens for document chunking during indexing + additionalProperties: false + required: + - documents + - vector_db_id + - chunk_size_in_tokens + title: InsertRequest + DefaultRAGQueryGeneratorConfig: + type: object + properties: + type: + type: string + const: default + default: default + description: >- + Type of query generator, always 'default' + separator: + type: string + default: ' ' + description: >- + String separator used to join query terms + additionalProperties: false + required: + - type + - separator + title: DefaultRAGQueryGeneratorConfig + description: >- + Configuration for the default RAG query generator. + LLMRAGQueryGeneratorConfig: + type: object + properties: + type: + type: string + const: llm + default: llm + description: Type of query generator, always 'llm' + model: + type: string + description: >- + Name of the language model to use for query generation + template: + type: string + description: >- + Template string for formatting the query generation prompt + additionalProperties: false + required: + - type + - model + - template + title: LLMRAGQueryGeneratorConfig + description: >- + Configuration for the LLM-based RAG query generator. + RAGQueryConfig: + type: object + properties: + query_generator_config: + oneOf: + - $ref: '#/components/schemas/DefaultRAGQueryGeneratorConfig' + - $ref: '#/components/schemas/LLMRAGQueryGeneratorConfig' + discriminator: + propertyName: type + mapping: + default: '#/components/schemas/DefaultRAGQueryGeneratorConfig' + llm: '#/components/schemas/LLMRAGQueryGeneratorConfig' + description: Configuration for the query generator. + max_tokens_in_context: + type: integer + default: 4096 + description: Maximum number of tokens in the context. + max_chunks: + type: integer + default: 5 + description: Maximum number of chunks to retrieve. + chunk_template: + type: string + default: > + Result {index} + + Content: {chunk.content} + + Metadata: {metadata} + description: >- + Template for formatting each retrieved chunk in the context. Available + placeholders: {index} (1-based chunk ordinal), {chunk.content} (chunk + content string), {metadata} (chunk metadata dict). Default: "Result {index}\nContent: + {chunk.content}\nMetadata: {metadata}\n" + mode: + $ref: '#/components/schemas/RAGSearchMode' + default: vector + description: >- + Search mode for retrieval—either "vector", "keyword", or "hybrid". Default + "vector". + ranker: + $ref: '#/components/schemas/Ranker' + description: >- + Configuration for the ranker to use in hybrid search. Defaults to RRF + ranker. + additionalProperties: false + required: + - query_generator_config + - max_tokens_in_context + - max_chunks + - chunk_template + title: RAGQueryConfig + description: >- + Configuration for the RAG query generation. + RAGSearchMode: + type: string + enum: + - vector + - keyword + - hybrid + title: RAGSearchMode + description: >- + Search modes for RAG query retrieval: - VECTOR: Uses vector similarity search + for semantic matching - KEYWORD: Uses keyword-based search for exact matching + - HYBRID: Combines both vector and keyword search for better results + RRFRanker: + type: object + properties: + type: + type: string + const: rrf + default: rrf + description: The type of ranker, always "rrf" + impact_factor: + type: number + default: 60.0 + description: >- + The impact factor for RRF scoring. Higher values give more weight to higher-ranked + results. Must be greater than 0 + additionalProperties: false + required: + - type + - impact_factor + title: RRFRanker + description: >- + Reciprocal Rank Fusion (RRF) ranker configuration. + Ranker: + oneOf: + - $ref: '#/components/schemas/RRFRanker' + - $ref: '#/components/schemas/WeightedRanker' + discriminator: + propertyName: type + mapping: + rrf: '#/components/schemas/RRFRanker' + weighted: '#/components/schemas/WeightedRanker' + WeightedRanker: + type: object + properties: + type: + type: string + const: weighted + default: weighted + description: The type of ranker, always "weighted" + alpha: + type: number + default: 0.5 + description: >- + Weight factor between 0 and 1. 0 means only use keyword scores, 1 means + only use vector scores, values in between blend both scores. + additionalProperties: false + required: + - type + - alpha + title: WeightedRanker + description: >- + Weighted ranker configuration that combines vector and keyword scores. + QueryRequest: + type: object + properties: + content: + $ref: '#/components/schemas/InterleavedContent' + description: >- + The query content to search for in the indexed documents + vector_db_ids: + type: array + items: + type: string + description: >- + List of vector database IDs to search within + query_config: + $ref: '#/components/schemas/RAGQueryConfig' + description: >- + (Optional) Configuration parameters for the query operation + additionalProperties: false + required: + - content + - vector_db_ids + title: QueryRequest + RAGQueryResult: + type: object + properties: + content: + $ref: '#/components/schemas/InterleavedContent' + description: >- + (Optional) The retrieved content from the query + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + Additional metadata about the query result + additionalProperties: false + required: + - metadata + title: RAGQueryResult + description: >- + Result of a RAG query containing retrieved content and metadata. + ToolGroup: + type: object + properties: + identifier: + type: string + provider_resource_id: + type: string + provider_id: + type: string + type: + type: string + enum: + - model + - shield + - vector_store + - dataset + - scoring_function + - benchmark + - tool + - tool_group + - prompt + const: tool_group + default: tool_group + description: Type of resource, always 'tool_group' + mcp_endpoint: + $ref: '#/components/schemas/URL' + description: >- + (Optional) Model Context Protocol endpoint for remote tools + args: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Additional arguments for the tool group + additionalProperties: false + required: + - identifier + - provider_id + - type + title: ToolGroup + description: >- + A group of related tools managed together. + ListToolGroupsResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/ToolGroup' + description: List of tool groups + additionalProperties: false + required: + - data + title: ListToolGroupsResponse + description: >- + Response containing a list of tool groups. + RegisterToolGroupRequest: + type: object + properties: + toolgroup_id: + type: string + description: The ID of the tool group to register. + provider_id: + type: string + description: >- + The ID of the provider to use for the tool group. + mcp_endpoint: + $ref: '#/components/schemas/URL' + description: >- + The MCP endpoint to use for the tool group. + args: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + A dictionary of arguments to pass to the tool group. + additionalProperties: false + required: + - toolgroup_id + - provider_id + title: RegisterToolGroupRequest + Chunk: + type: object + properties: + content: + $ref: '#/components/schemas/InterleavedContent' + description: >- + The content of the chunk, which can be interleaved text, images, or other + types. + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + Metadata associated with the chunk that will be used in the model context + during inference. + embedding: + type: array + items: + type: number + description: >- + Optional embedding for the chunk. If not provided, it will be computed + later. + stored_chunk_id: + type: string + description: >- + The chunk ID that is stored in the vector database. Used for backend functionality. + chunk_metadata: + $ref: '#/components/schemas/ChunkMetadata' + description: >- + Metadata for the chunk that will NOT be used in the context during inference. + The `chunk_metadata` is required backend functionality. + additionalProperties: false + required: + - content + - metadata + title: Chunk + description: >- + A chunk of content that can be inserted into a vector database. + ChunkMetadata: + type: object + properties: + chunk_id: + type: string + description: >- + The ID of the chunk. If not set, it will be generated based on the document + ID and content. + document_id: + type: string + description: >- + The ID of the document this chunk belongs to. + source: + type: string + description: >- + The source of the content, such as a URL, file path, or other identifier. + created_timestamp: + type: integer + description: >- + An optional timestamp indicating when the chunk was created. + updated_timestamp: + type: integer + description: >- + An optional timestamp indicating when the chunk was last updated. + chunk_window: + type: string + description: >- + The window of the chunk, which can be used to group related chunks together. + chunk_tokenizer: + type: string + description: >- + The tokenizer used to create the chunk. Default is Tiktoken. + chunk_embedding_model: + type: string + description: >- + The embedding model used to create the chunk's embedding. + chunk_embedding_dimension: + type: integer + description: >- + The dimension of the embedding vector for the chunk. + content_token_count: + type: integer + description: >- + The number of tokens in the content of the chunk. + metadata_token_count: + type: integer + description: >- + The number of tokens in the metadata of the chunk. + additionalProperties: false + title: ChunkMetadata + description: >- + `ChunkMetadata` is backend metadata for a `Chunk` that is used to store additional + information about the chunk that will not be used in the context during + inference, but is required for backend functionality. The `ChunkMetadata` is + set during chunk creation in `MemoryToolRuntimeImpl().insert()`and is not + expected to change after. Use `Chunk.metadata` for metadata that will + be used in the context during inference. + InsertChunksRequest: + type: object + properties: + vector_db_id: + type: string + description: >- + The identifier of the vector database to insert the chunks into. + chunks: + type: array + items: + $ref: '#/components/schemas/Chunk' + description: >- + The chunks to insert. Each `Chunk` should contain content which can be + interleaved text, images, or other types. `metadata`: `dict[str, Any]` + and `embedding`: `List[float]` are optional. If `metadata` is provided, + you configure how Llama Stack formats the chunk during generation. If + `embedding` is not provided, it will be computed later. + ttl_seconds: + type: integer + description: The time to live of the chunks. + additionalProperties: false + required: + - vector_db_id + - chunks + title: InsertChunksRequest + QueryChunksRequest: + type: object + properties: + vector_db_id: + type: string + description: >- + The identifier of the vector database to query. + query: + $ref: '#/components/schemas/InterleavedContent' + description: The query to search for. + params: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The parameters of the query. + additionalProperties: false + required: + - vector_db_id + - query + title: QueryChunksRequest + QueryChunksResponse: + type: object + properties: + chunks: + type: array + items: + $ref: '#/components/schemas/Chunk' + description: >- + List of content chunks returned from the query + scores: + type: array + items: + type: number + description: >- + Relevance scores corresponding to each returned chunk + additionalProperties: false + required: + - chunks + - scores + title: QueryChunksResponse + description: >- + Response from querying chunks in a vector database. + VectorStoreFileCounts: + type: object + properties: + completed: + type: integer + description: >- + Number of files that have been successfully processed + cancelled: + type: integer + description: >- + Number of files that had their processing cancelled + failed: + type: integer + description: Number of files that failed to process + in_progress: + type: integer + description: >- + Number of files currently being processed + total: + type: integer + description: >- + Total number of files in the vector store + additionalProperties: false + required: + - completed + - cancelled + - failed + - in_progress + - total + title: VectorStoreFileCounts + description: >- + File processing status counts for a vector store. + VectorStoreListResponse: + type: object + properties: + object: + type: string + default: list + description: Object type identifier, always "list" + data: + type: array + items: + $ref: '#/components/schemas/VectorStoreObject' + description: List of vector store objects + first_id: + type: string + description: >- + (Optional) ID of the first vector store in the list for pagination + last_id: + type: string + description: >- + (Optional) ID of the last vector store in the list for pagination + has_more: + type: boolean + default: false + description: >- + Whether there are more vector stores available beyond this page + additionalProperties: false + required: + - object + - data + - has_more + title: VectorStoreListResponse + description: Response from listing vector stores. + VectorStoreObject: + type: object + properties: + id: + type: string + description: Unique identifier for the vector store + object: + type: string + default: vector_store + description: >- + Object type identifier, always "vector_store" + created_at: + type: integer + description: >- + Timestamp when the vector store was created + name: + type: string + description: (Optional) Name of the vector store + usage_bytes: + type: integer + default: 0 + description: >- + Storage space used by the vector store in bytes + file_counts: + $ref: '#/components/schemas/VectorStoreFileCounts' + description: >- + File processing status counts for the vector store + status: + type: string + default: completed + description: Current status of the vector store + expires_after: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Expiration policy for the vector store + expires_at: + type: integer + description: >- + (Optional) Timestamp when the vector store will expire + last_active_at: + type: integer + description: >- + (Optional) Timestamp of last activity on the vector store + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + Set of key-value pairs that can be attached to the vector store + additionalProperties: false + required: + - id + - object + - created_at + - usage_bytes + - file_counts + - status + - metadata + title: VectorStoreObject + description: OpenAI Vector Store object. + "OpenAICreateVectorStoreRequestWithExtraBody": + type: object + properties: + name: + type: string + description: (Optional) A name for the vector store + file_ids: + type: array + items: + type: string + description: >- + List of file IDs to include in the vector store + expires_after: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Expiration policy for the vector store + chunking_strategy: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Strategy for splitting files into chunks + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + Set of key-value pairs that can be attached to the vector store + additionalProperties: false + title: >- + OpenAICreateVectorStoreRequestWithExtraBody + description: >- + Request to create a vector store with extra_body support. + OpenaiUpdateVectorStoreRequest: + type: object + properties: + name: + type: string + description: The name of the vector store. + expires_after: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + The expiration policy for a vector store. + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + Set of 16 key-value pairs that can be attached to an object. + additionalProperties: false + title: OpenaiUpdateVectorStoreRequest + VectorStoreDeleteResponse: + type: object + properties: + id: + type: string + description: >- + Unique identifier of the deleted vector store + object: + type: string + default: vector_store.deleted + description: >- + Object type identifier for the deletion response + deleted: + type: boolean + default: true + description: >- + Whether the deletion operation was successful + additionalProperties: false + required: + - id + - object + - deleted + title: VectorStoreDeleteResponse + description: Response from deleting a vector store. + VectorStoreChunkingStrategy: + oneOf: + - $ref: '#/components/schemas/VectorStoreChunkingStrategyAuto' + - $ref: '#/components/schemas/VectorStoreChunkingStrategyStatic' + discriminator: + propertyName: type + mapping: + auto: '#/components/schemas/VectorStoreChunkingStrategyAuto' + static: '#/components/schemas/VectorStoreChunkingStrategyStatic' + VectorStoreChunkingStrategyAuto: + type: object + properties: + type: + type: string + const: auto + default: auto + description: >- + Strategy type, always "auto" for automatic chunking + additionalProperties: false + required: + - type + title: VectorStoreChunkingStrategyAuto + description: >- + Automatic chunking strategy for vector store files. + VectorStoreChunkingStrategyStatic: + type: object + properties: + type: + type: string + const: static + default: static + description: >- + Strategy type, always "static" for static chunking + static: + $ref: '#/components/schemas/VectorStoreChunkingStrategyStaticConfig' + description: >- + Configuration parameters for the static chunking strategy + additionalProperties: false + required: + - type + - static + title: VectorStoreChunkingStrategyStatic + description: >- + Static chunking strategy with configurable parameters. + VectorStoreChunkingStrategyStaticConfig: + type: object + properties: + chunk_overlap_tokens: + type: integer + default: 400 + description: >- + Number of tokens to overlap between adjacent chunks + max_chunk_size_tokens: + type: integer + default: 800 + description: >- + Maximum number of tokens per chunk, must be between 100 and 4096 + additionalProperties: false + required: + - chunk_overlap_tokens + - max_chunk_size_tokens + title: VectorStoreChunkingStrategyStaticConfig + description: >- + Configuration for static chunking strategy. + "OpenAICreateVectorStoreFileBatchRequestWithExtraBody": + type: object + properties: + file_ids: + type: array + items: + type: string + description: >- + A list of File IDs that the vector store should use + attributes: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Key-value attributes to store with the files + chunking_strategy: + $ref: '#/components/schemas/VectorStoreChunkingStrategy' + description: >- + (Optional) The chunking strategy used to chunk the file(s). Defaults to + auto + additionalProperties: false + required: + - file_ids + title: >- + OpenAICreateVectorStoreFileBatchRequestWithExtraBody + description: >- + Request to create a vector store file batch with extra_body support. + VectorStoreFileBatchObject: + type: object + properties: + id: + type: string + description: Unique identifier for the file batch + object: + type: string + default: vector_store.file_batch + description: >- + Object type identifier, always "vector_store.file_batch" + created_at: + type: integer + description: >- + Timestamp when the file batch was created + vector_store_id: + type: string + description: >- + ID of the vector store containing the file batch + status: + $ref: '#/components/schemas/VectorStoreFileStatus' + description: >- + Current processing status of the file batch + file_counts: + $ref: '#/components/schemas/VectorStoreFileCounts' + description: >- + File processing status counts for the batch + additionalProperties: false + required: + - id + - object + - created_at + - vector_store_id + - status + - file_counts + title: VectorStoreFileBatchObject + description: OpenAI Vector Store File Batch object. + VectorStoreFileStatus: + oneOf: + - type: string + const: completed + - type: string + const: in_progress + - type: string + const: cancelled + - type: string + const: failed + VectorStoreFileLastError: + type: object + properties: + code: + oneOf: + - type: string + const: server_error + - type: string + const: rate_limit_exceeded + description: >- + Error code indicating the type of failure + message: + type: string + description: >- + Human-readable error message describing the failure + additionalProperties: false + required: + - code + - message + title: VectorStoreFileLastError + description: >- + Error information for failed vector store file processing. + VectorStoreFileObject: + type: object + properties: + id: + type: string + description: Unique identifier for the file + object: + type: string + default: vector_store.file + description: >- + Object type identifier, always "vector_store.file" + attributes: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + Key-value attributes associated with the file + chunking_strategy: + oneOf: + - $ref: '#/components/schemas/VectorStoreChunkingStrategyAuto' + - $ref: '#/components/schemas/VectorStoreChunkingStrategyStatic' + discriminator: + propertyName: type + mapping: + auto: '#/components/schemas/VectorStoreChunkingStrategyAuto' + static: '#/components/schemas/VectorStoreChunkingStrategyStatic' + description: >- + Strategy used for splitting the file into chunks + created_at: + type: integer + description: >- + Timestamp when the file was added to the vector store + last_error: + $ref: '#/components/schemas/VectorStoreFileLastError' + description: >- + (Optional) Error information if file processing failed + status: + $ref: '#/components/schemas/VectorStoreFileStatus' + description: Current processing status of the file + usage_bytes: + type: integer + default: 0 + description: Storage space used by this file in bytes + vector_store_id: + type: string + description: >- + ID of the vector store containing this file + additionalProperties: false + required: + - id + - object + - attributes + - chunking_strategy + - created_at + - status + - usage_bytes + - vector_store_id + title: VectorStoreFileObject + description: OpenAI Vector Store File object. + VectorStoreFilesListInBatchResponse: + type: object + properties: + object: + type: string + default: list + description: Object type identifier, always "list" + data: + type: array + items: + $ref: '#/components/schemas/VectorStoreFileObject' + description: >- + List of vector store file objects in the batch + first_id: + type: string + description: >- + (Optional) ID of the first file in the list for pagination + last_id: + type: string + description: >- + (Optional) ID of the last file in the list for pagination + has_more: + type: boolean + default: false + description: >- + Whether there are more files available beyond this page + additionalProperties: false + required: + - object + - data + - has_more + title: VectorStoreFilesListInBatchResponse + description: >- + Response from listing files in a vector store file batch. + VectorStoreListFilesResponse: + type: object + properties: + object: + type: string + default: list + description: Object type identifier, always "list" + data: + type: array + items: + $ref: '#/components/schemas/VectorStoreFileObject' + description: List of vector store file objects + first_id: + type: string + description: >- + (Optional) ID of the first file in the list for pagination + last_id: + type: string + description: >- + (Optional) ID of the last file in the list for pagination + has_more: + type: boolean + default: false + description: >- + Whether there are more files available beyond this page + additionalProperties: false + required: + - object + - data + - has_more + title: VectorStoreListFilesResponse + description: >- + Response from listing files in a vector store. + OpenaiAttachFileToVectorStoreRequest: + type: object + properties: + file_id: + type: string + description: >- + The ID of the file to attach to the vector store. + attributes: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + The key-value attributes stored with the file, which can be used for filtering. + chunking_strategy: + $ref: '#/components/schemas/VectorStoreChunkingStrategy' + description: >- + The chunking strategy to use for the file. + additionalProperties: false + required: + - file_id + title: OpenaiAttachFileToVectorStoreRequest + OpenaiUpdateVectorStoreFileRequest: + type: object + properties: + attributes: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + The updated key-value attributes to store with the file. + additionalProperties: false + required: + - attributes + title: OpenaiUpdateVectorStoreFileRequest + VectorStoreFileDeleteResponse: + type: object + properties: + id: + type: string + description: Unique identifier of the deleted file + object: + type: string + default: vector_store.file.deleted + description: >- + Object type identifier for the deletion response + deleted: + type: boolean + default: true + description: >- + Whether the deletion operation was successful + additionalProperties: false + required: + - id + - object + - deleted + title: VectorStoreFileDeleteResponse + description: >- + Response from deleting a vector store file. + VectorStoreContent: + type: object + properties: + type: + type: string + const: text + description: >- + Content type, currently only "text" is supported + text: + type: string + description: The actual text content + additionalProperties: false + required: + - type + - text + title: VectorStoreContent + description: >- + Content item from a vector store file or search result. + VectorStoreFileContentsResponse: + type: object + properties: + file_id: + type: string + description: Unique identifier for the file + filename: + type: string + description: Name of the file + attributes: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + Key-value attributes associated with the file + content: + type: array + items: + $ref: '#/components/schemas/VectorStoreContent' + description: List of content items from the file + additionalProperties: false + required: + - file_id + - filename + - attributes + - content + title: VectorStoreFileContentsResponse + description: >- + Response from retrieving the contents of a vector store file. + OpenaiSearchVectorStoreRequest: + type: object + properties: + query: + oneOf: + - type: string + - type: array + items: + type: string + description: >- + The query string or array for performing the search. + filters: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + Filters based on file attributes to narrow the search results. + max_num_results: + type: integer + description: >- + Maximum number of results to return (1 to 50 inclusive, default 10). + ranking_options: + type: object + properties: + ranker: + type: string + description: >- + (Optional) Name of the ranking algorithm to use + score_threshold: + type: number + default: 0.0 + description: >- + (Optional) Minimum relevance score threshold for results + additionalProperties: false + description: >- + Ranking options for fine-tuning the search results. + rewrite_query: + type: boolean + description: >- + Whether to rewrite the natural language query for vector search (default + false) + search_mode: + type: string + description: >- + The search mode to use - "keyword", "vector", or "hybrid" (default "vector") + additionalProperties: false + required: + - query + title: OpenaiSearchVectorStoreRequest + VectorStoreSearchResponse: + type: object + properties: + file_id: + type: string + description: >- + Unique identifier of the file containing the result + filename: + type: string + description: Name of the file containing the result + score: + type: number + description: Relevance score for this search result + attributes: + type: object + additionalProperties: + oneOf: + - type: string + - type: number + - type: boolean + description: >- + (Optional) Key-value attributes associated with the file + content: + type: array + items: + $ref: '#/components/schemas/VectorStoreContent' + description: >- + List of content items matching the search query + additionalProperties: false + required: + - file_id + - filename + - score + - content + title: VectorStoreSearchResponse + description: Response from searching a vector store. + VectorStoreSearchResponsePage: + type: object + properties: + object: + type: string + default: vector_store.search_results.page + description: >- + Object type identifier for the search results page + search_query: + type: string + description: >- + The original search query that was executed + data: + type: array + items: + $ref: '#/components/schemas/VectorStoreSearchResponse' + description: List of search result objects + has_more: + type: boolean + default: false + description: >- + Whether there are more results available beyond this page + next_page: + type: string + description: >- + (Optional) Token for retrieving the next page of results + additionalProperties: false + required: + - object + - search_query + - data + - has_more + title: VectorStoreSearchResponsePage + description: >- + Paginated response from searching a vector store. + VersionInfo: + type: object + properties: + version: + type: string + description: Version number of the service + additionalProperties: false + required: + - version + title: VersionInfo + description: Version information for the service. + AppendRowsRequest: + type: object + properties: + rows: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The rows to append to the dataset. + additionalProperties: false + required: + - rows + title: AppendRowsRequest + PaginatedResponse: + type: object + properties: + data: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The list of items for the current page + has_more: + type: boolean + description: >- + Whether there are more items available after this set + url: + type: string + description: The URL for accessing this list + additionalProperties: false + required: + - data + - has_more + title: PaginatedResponse + description: >- + A generic paginated response that follows a simple format. + Dataset: + type: object + properties: + identifier: + type: string + provider_resource_id: + type: string + provider_id: + type: string + type: + type: string + enum: + - model + - shield + - vector_store + - dataset + - scoring_function + - benchmark + - tool + - tool_group + - prompt + const: dataset + default: dataset + description: >- + Type of resource, always 'dataset' for datasets + purpose: + type: string + enum: + - post-training/messages + - eval/question-answer + - eval/messages-answer + description: >- + Purpose of the dataset indicating its intended use + source: + oneOf: + - $ref: '#/components/schemas/URIDataSource' + - $ref: '#/components/schemas/RowsDataSource' + discriminator: + propertyName: type + mapping: + uri: '#/components/schemas/URIDataSource' + rows: '#/components/schemas/RowsDataSource' + description: >- + Data source configuration for the dataset + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: Additional metadata for the dataset + additionalProperties: false + required: + - identifier + - provider_id + - type + - purpose + - source + - metadata + title: Dataset + description: >- + Dataset resource for storing and accessing training or evaluation data. + RowsDataSource: + type: object + properties: + type: + type: string + const: rows + default: rows + rows: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + The dataset is stored in rows. E.g. - [ {"messages": [{"role": "user", + "content": "Hello, world!"}, {"role": "assistant", "content": "Hello, + world!"}]} ] + additionalProperties: false + required: + - type + - rows + title: RowsDataSource + description: A dataset stored in rows. + URIDataSource: + type: object + properties: + type: + type: string + const: uri + default: uri + uri: + type: string + description: >- + The dataset can be obtained from a URI. E.g. - "https://mywebsite.com/mydata.jsonl" + - "lsfs://mydata.jsonl" - "data:csv;base64,{base64_content}" + additionalProperties: false + required: + - type + - uri + title: URIDataSource + description: >- + A dataset that can be obtained from a URI. + ListDatasetsResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Dataset' + description: List of datasets + additionalProperties: false + required: + - data + title: ListDatasetsResponse + description: Response from listing datasets. + DataSource: + oneOf: + - $ref: '#/components/schemas/URIDataSource' + - $ref: '#/components/schemas/RowsDataSource' + discriminator: + propertyName: type + mapping: + uri: '#/components/schemas/URIDataSource' + rows: '#/components/schemas/RowsDataSource' + RegisterDatasetRequest: + type: object + properties: + purpose: + type: string + enum: + - post-training/messages + - eval/question-answer + - eval/messages-answer + description: >- + The purpose of the dataset. One of: - "post-training/messages": The dataset + contains a messages column with list of messages for post-training. { + "messages": [ {"role": "user", "content": "Hello, world!"}, {"role": "assistant", + "content": "Hello, world!"}, ] } - "eval/question-answer": The dataset + contains a question column and an answer column for evaluation. { "question": + "What is the capital of France?", "answer": "Paris" } - "eval/messages-answer": + The dataset contains a messages column with list of messages and an answer + column for evaluation. { "messages": [ {"role": "user", "content": "Hello, + my name is John Doe."}, {"role": "assistant", "content": "Hello, John + Doe. How can I help you today?"}, {"role": "user", "content": "What's + my name?"}, ], "answer": "John Doe" } + source: + $ref: '#/components/schemas/DataSource' + description: >- + The data source of the dataset. Ensure that the data source schema is + compatible with the purpose of the dataset. Examples: - { "type": "uri", + "uri": "https://mywebsite.com/mydata.jsonl" } - { "type": "uri", "uri": + "lsfs://mydata.jsonl" } - { "type": "uri", "uri": "data:csv;base64,{base64_content}" + } - { "type": "uri", "uri": "huggingface://llamastack/simpleqa?split=train" + } - { "type": "rows", "rows": [ { "messages": [ {"role": "user", "content": + "Hello, world!"}, {"role": "assistant", "content": "Hello, world!"}, ] + } ] } + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + The metadata for the dataset. - E.g. {"description": "My dataset"}. + dataset_id: + type: string + description: >- + The ID of the dataset. If not provided, an ID will be generated. + additionalProperties: false + required: + - purpose + - source + title: RegisterDatasetRequest + AgentConfig: + type: object + properties: + sampling_params: + $ref: '#/components/schemas/SamplingParams' + input_shields: + type: array + items: + type: string + output_shields: + type: array + items: + type: string + toolgroups: + type: array + items: + $ref: '#/components/schemas/AgentTool' + client_tools: + type: array + items: + $ref: '#/components/schemas/ToolDef' + tool_choice: + type: string + enum: + - auto + - required + - none + title: ToolChoice + description: >- + Whether tool use is required or automatic. This is a hint to the model + which may not be followed. It depends on the Instruction Following capabilities + of the model. + deprecated: true + tool_prompt_format: + type: string + enum: + - json + - function_tag + - python_list + title: ToolPromptFormat + description: >- + Prompt format for calling custom / zero shot tools. + deprecated: true + tool_config: + $ref: '#/components/schemas/ToolConfig' + max_infer_iters: + type: integer + default: 10 + model: + type: string + description: >- + The model identifier to use for the agent + instructions: + type: string + description: The system instructions for the agent + name: + type: string + description: >- + Optional name for the agent, used in telemetry and identification + enable_session_persistence: + type: boolean + default: false + description: >- + Optional flag indicating whether session data has to be persisted + response_format: + $ref: '#/components/schemas/ResponseFormat' + description: Optional response format configuration + additionalProperties: false + required: + - model + - instructions + title: AgentConfig + description: Configuration for an agent. + AgentTool: + oneOf: + - type: string + - type: object + properties: + name: + type: string + args: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + additionalProperties: false + required: + - name + - args + title: AgentToolGroupWithArgs + GrammarResponseFormat: + type: object + properties: + type: + type: string + enum: + - json_schema + - grammar + description: >- + Must be "grammar" to identify this format type + const: grammar + default: grammar + bnf: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + The BNF grammar specification the response should conform to + additionalProperties: false + required: + - type + - bnf + title: GrammarResponseFormat + description: >- + Configuration for grammar-guided response generation. + GreedySamplingStrategy: + type: object + properties: + type: + type: string + const: greedy + default: greedy + description: >- + Must be "greedy" to identify this sampling strategy + additionalProperties: false + required: + - type + title: GreedySamplingStrategy + description: >- + Greedy sampling strategy that selects the highest probability token at each + step. + JsonSchemaResponseFormat: + type: object + properties: + type: + type: string + enum: + - json_schema + - grammar + description: >- + Must be "json_schema" to identify this format type + const: json_schema + default: json_schema + json_schema: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + The JSON schema the response should conform to. In a Python SDK, this + is often a `pydantic` model. + additionalProperties: false + required: + - type + - json_schema + title: JsonSchemaResponseFormat + description: >- + Configuration for JSON schema-guided response generation. + ResponseFormat: + oneOf: + - $ref: '#/components/schemas/JsonSchemaResponseFormat' + - $ref: '#/components/schemas/GrammarResponseFormat' + discriminator: + propertyName: type + mapping: + json_schema: '#/components/schemas/JsonSchemaResponseFormat' + grammar: '#/components/schemas/GrammarResponseFormat' + SamplingParams: + type: object + properties: + strategy: + oneOf: + - $ref: '#/components/schemas/GreedySamplingStrategy' + - $ref: '#/components/schemas/TopPSamplingStrategy' + - $ref: '#/components/schemas/TopKSamplingStrategy' + discriminator: + propertyName: type + mapping: + greedy: '#/components/schemas/GreedySamplingStrategy' + top_p: '#/components/schemas/TopPSamplingStrategy' + top_k: '#/components/schemas/TopKSamplingStrategy' + description: The sampling strategy. + max_tokens: + type: integer + default: 0 + description: >- + The maximum number of tokens that can be generated in the completion. + The token count of your prompt plus max_tokens cannot exceed the model's + context length. + repetition_penalty: + type: number + default: 1.0 + description: >- + Number between -2.0 and 2.0. Positive values penalize new tokens based + on whether they appear in the text so far, increasing the model's likelihood + to talk about new topics. + stop: + type: array + items: + type: string + description: >- + Up to 4 sequences where the API will stop generating further tokens. The + returned text will not contain the stop sequence. + additionalProperties: false + required: + - strategy + title: SamplingParams + description: Sampling parameters. + ToolConfig: + type: object + properties: + tool_choice: + oneOf: + - type: string + enum: + - auto + - required + - none + title: ToolChoice + description: >- + Whether tool use is required or automatic. This is a hint to the model + which may not be followed. It depends on the Instruction Following + capabilities of the model. + - type: string + default: auto + description: >- + (Optional) Whether tool use is automatic, required, or none. Can also + specify a tool name to use a specific tool. Defaults to ToolChoice.auto. + tool_prompt_format: + type: string + enum: + - json + - function_tag + - python_list + description: >- + (Optional) Instructs the model how to format tool calls. By default, Llama + Stack will attempt to use a format that is best adapted to the model. + - `ToolPromptFormat.json`: The tool calls are formatted as a JSON object. + - `ToolPromptFormat.function_tag`: The tool calls are enclosed in a + tag. - `ToolPromptFormat.python_list`: The tool calls are output as Python + syntax -- a list of function calls. + system_message_behavior: + type: string + enum: + - append + - replace + description: >- + (Optional) Config for how to override the default system prompt. - `SystemMessageBehavior.append`: + Appends the provided system message to the default system prompt. - `SystemMessageBehavior.replace`: + Replaces the default system prompt with the provided system message. The + system message can include the string '{{function_definitions}}' to indicate + where the function definitions should be inserted. + default: append + additionalProperties: false + title: ToolConfig + description: Configuration for tool use. + TopKSamplingStrategy: + type: object + properties: + type: + type: string + const: top_k + default: top_k + description: >- + Must be "top_k" to identify this sampling strategy + top_k: + type: integer + description: >- + Number of top tokens to consider for sampling. Must be at least 1 + additionalProperties: false + required: + - type + - top_k + title: TopKSamplingStrategy + description: >- + Top-k sampling strategy that restricts sampling to the k most likely tokens. + TopPSamplingStrategy: + type: object + properties: + type: + type: string + const: top_p + default: top_p + description: >- + Must be "top_p" to identify this sampling strategy + temperature: + type: number + description: >- + Controls randomness in sampling. Higher values increase randomness + top_p: + type: number + default: 0.95 + description: >- + Cumulative probability threshold for nucleus sampling. Defaults to 0.95 + additionalProperties: false + required: + - type + title: TopPSamplingStrategy + description: >- + Top-p (nucleus) sampling strategy that samples from the smallest set of tokens + with cumulative probability >= p. + CreateAgentRequest: + type: object + properties: + agent_config: + $ref: '#/components/schemas/AgentConfig' + description: The configuration for the agent. + additionalProperties: false + required: + - agent_config + title: CreateAgentRequest + AgentCreateResponse: + type: object + properties: + agent_id: + type: string + description: Unique identifier for the created agent + additionalProperties: false + required: + - agent_id + title: AgentCreateResponse + description: >- + Response returned when creating a new agent. + Agent: + type: object + properties: + agent_id: + type: string + description: Unique identifier for the agent + agent_config: + $ref: '#/components/schemas/AgentConfig' + description: Configuration settings for the agent + created_at: + type: string + format: date-time + description: Timestamp when the agent was created + additionalProperties: false + required: + - agent_id + - agent_config + - created_at + title: Agent + description: >- + An agent instance with configuration and metadata. + CreateAgentSessionRequest: + type: object + properties: + session_name: + type: string + description: The name of the session to create. + additionalProperties: false + required: + - session_name + title: CreateAgentSessionRequest + AgentSessionCreateResponse: + type: object + properties: + session_id: + type: string + description: >- + Unique identifier for the created session + additionalProperties: false + required: + - session_id + title: AgentSessionCreateResponse + description: >- + Response returned when creating a new agent session. + InferenceStep: + type: object + properties: + turn_id: + type: string + description: The ID of the turn. + step_id: + type: string + description: The ID of the step. + started_at: + type: string + format: date-time + description: The time the step started. + completed_at: + type: string + format: date-time + description: The time the step completed. + step_type: + type: string + enum: + - inference + - tool_execution + - shield_call + - memory_retrieval + title: StepType + description: Type of the step in an agent turn. + const: inference + default: inference + model_response: + $ref: '#/components/schemas/CompletionMessage' + description: The response from the LLM. + additionalProperties: false + required: + - turn_id + - step_id + - step_type + - model_response + title: InferenceStep + description: An inference step in an agent turn. + MemoryRetrievalStep: + type: object + properties: + turn_id: + type: string + description: The ID of the turn. + step_id: + type: string + description: The ID of the step. + started_at: + type: string + format: date-time + description: The time the step started. + completed_at: + type: string + format: date-time + description: The time the step completed. + step_type: + type: string + enum: + - inference + - tool_execution + - shield_call + - memory_retrieval + title: StepType + description: Type of the step in an agent turn. + const: memory_retrieval + default: memory_retrieval + vector_db_ids: + type: string + description: >- + The IDs of the vector databases to retrieve context from. + inserted_context: + $ref: '#/components/schemas/InterleavedContent' + description: >- + The context retrieved from the vector databases. + additionalProperties: false + required: + - turn_id + - step_id + - step_type + - vector_db_ids + - inserted_context + title: MemoryRetrievalStep + description: >- + A memory retrieval step in an agent turn. + Session: + type: object + properties: + session_id: + type: string + description: >- + Unique identifier for the conversation session + session_name: + type: string + description: Human-readable name for the session + turns: + type: array + items: + $ref: '#/components/schemas/Turn' + description: >- + List of all turns that have occurred in this session + started_at: + type: string + format: date-time + description: Timestamp when the session was created + additionalProperties: false + required: + - session_id + - session_name + - turns + - started_at + title: Session + description: >- + A single session of an interaction with an Agentic System. + ShieldCallStep: + type: object + properties: + turn_id: + type: string + description: The ID of the turn. + step_id: + type: string + description: The ID of the step. + started_at: + type: string + format: date-time + description: The time the step started. + completed_at: + type: string + format: date-time + description: The time the step completed. + step_type: + type: string + enum: + - inference + - tool_execution + - shield_call + - memory_retrieval + title: StepType + description: Type of the step in an agent turn. + const: shield_call + default: shield_call + violation: + $ref: '#/components/schemas/SafetyViolation' + description: The violation from the shield call. + additionalProperties: false + required: + - turn_id + - step_id + - step_type + title: ShieldCallStep + description: A shield call step in an agent turn. + ToolExecutionStep: + type: object + properties: + turn_id: + type: string + description: The ID of the turn. + step_id: + type: string + description: The ID of the step. + started_at: + type: string + format: date-time + description: The time the step started. + completed_at: + type: string + format: date-time + description: The time the step completed. + step_type: + type: string + enum: + - inference + - tool_execution + - shield_call + - memory_retrieval + title: StepType + description: Type of the step in an agent turn. + const: tool_execution + default: tool_execution + tool_calls: + type: array + items: + $ref: '#/components/schemas/ToolCall' + description: The tool calls to execute. + tool_responses: + type: array + items: + $ref: '#/components/schemas/ToolResponse' + description: The tool responses from the tool calls. + additionalProperties: false + required: + - turn_id + - step_id + - step_type + - tool_calls + - tool_responses + title: ToolExecutionStep + description: A tool execution step in an agent turn. + ToolResponse: + type: object + properties: + call_id: + type: string + description: >- + Unique identifier for the tool call this response is for + tool_name: + oneOf: + - type: string + enum: + - brave_search + - wolfram_alpha + - photogen + - code_interpreter + title: BuiltinTool + - type: string + description: Name of the tool that was invoked + content: + $ref: '#/components/schemas/InterleavedContent' + description: The response content from the tool + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Additional metadata about the tool response + additionalProperties: false + required: + - call_id + - tool_name + - content + title: ToolResponse + description: Response from a tool invocation. + Turn: + type: object + properties: + turn_id: + type: string + description: >- + Unique identifier for the turn within a session + session_id: + type: string + description: >- + Unique identifier for the conversation session + input_messages: + type: array + items: + oneOf: + - $ref: '#/components/schemas/UserMessage' + - $ref: '#/components/schemas/ToolResponseMessage' + description: >- + List of messages that initiated this turn + steps: + type: array + items: + oneOf: + - $ref: '#/components/schemas/InferenceStep' + - $ref: '#/components/schemas/ToolExecutionStep' + - $ref: '#/components/schemas/ShieldCallStep' + - $ref: '#/components/schemas/MemoryRetrievalStep' + discriminator: + propertyName: step_type + mapping: + inference: '#/components/schemas/InferenceStep' + tool_execution: '#/components/schemas/ToolExecutionStep' + shield_call: '#/components/schemas/ShieldCallStep' + memory_retrieval: '#/components/schemas/MemoryRetrievalStep' + description: >- + Ordered list of processing steps executed during this turn + output_message: + $ref: '#/components/schemas/CompletionMessage' + description: >- + The model's generated response containing content and metadata + output_attachments: + type: array + items: + type: object + properties: + content: + oneOf: + - type: string + - $ref: '#/components/schemas/InterleavedContentItem' + - type: array + items: + $ref: '#/components/schemas/InterleavedContentItem' + - $ref: '#/components/schemas/URL' + description: The content of the attachment. + mime_type: + type: string + description: The MIME type of the attachment. + additionalProperties: false + required: + - content + - mime_type + title: Attachment + description: An attachment to an agent turn. + description: >- + (Optional) Files or media attached to the agent's response + started_at: + type: string + format: date-time + description: Timestamp when the turn began + completed_at: + type: string + format: date-time + description: >- + (Optional) Timestamp when the turn finished, if completed + additionalProperties: false + required: + - turn_id + - session_id + - input_messages + - steps + - output_message + - started_at + title: Turn + description: >- + A single turn in an interaction with an Agentic System. + CreateAgentTurnRequest: + type: object + properties: + messages: + type: array + items: + oneOf: + - $ref: '#/components/schemas/UserMessage' + - $ref: '#/components/schemas/ToolResponseMessage' + description: List of messages to start the turn with. + stream: + type: boolean + description: >- + (Optional) If True, generate an SSE event stream of the response. Defaults + to False. + documents: + type: array + items: + type: object + properties: + content: + oneOf: + - type: string + - $ref: '#/components/schemas/InterleavedContentItem' + - type: array + items: + $ref: '#/components/schemas/InterleavedContentItem' + - $ref: '#/components/schemas/URL' + description: The content of the document. + mime_type: + type: string + description: The MIME type of the document. + additionalProperties: false + required: + - content + - mime_type + title: Document + description: A document to be used by an agent. + description: >- + (Optional) List of documents to create the turn with. + toolgroups: + type: array + items: + $ref: '#/components/schemas/AgentTool' + description: >- + (Optional) List of toolgroups to create the turn with, will be used in + addition to the agent's config toolgroups for the request. + tool_config: + $ref: '#/components/schemas/ToolConfig' + description: >- + (Optional) The tool configuration to create the turn with, will be used + to override the agent's tool_config. + additionalProperties: false + required: + - messages + title: CreateAgentTurnRequest + AgentTurnResponseEvent: + type: object + properties: + payload: + oneOf: + - $ref: '#/components/schemas/AgentTurnResponseStepStartPayload' + - $ref: '#/components/schemas/AgentTurnResponseStepProgressPayload' + - $ref: '#/components/schemas/AgentTurnResponseStepCompletePayload' + - $ref: '#/components/schemas/AgentTurnResponseTurnStartPayload' + - $ref: '#/components/schemas/AgentTurnResponseTurnCompletePayload' + - $ref: '#/components/schemas/AgentTurnResponseTurnAwaitingInputPayload' + discriminator: + propertyName: event_type + mapping: + step_start: '#/components/schemas/AgentTurnResponseStepStartPayload' + step_progress: '#/components/schemas/AgentTurnResponseStepProgressPayload' + step_complete: '#/components/schemas/AgentTurnResponseStepCompletePayload' + turn_start: '#/components/schemas/AgentTurnResponseTurnStartPayload' + turn_complete: '#/components/schemas/AgentTurnResponseTurnCompletePayload' + turn_awaiting_input: '#/components/schemas/AgentTurnResponseTurnAwaitingInputPayload' + description: >- + Event-specific payload containing event data + additionalProperties: false + required: + - payload + title: AgentTurnResponseEvent + description: >- + An event in an agent turn response stream. + AgentTurnResponseStepCompletePayload: + type: object + properties: + event_type: + type: string + enum: + - step_start + - step_complete + - step_progress + - turn_start + - turn_complete + - turn_awaiting_input + const: step_complete + default: step_complete + description: Type of event being reported + step_type: + type: string + enum: + - inference + - tool_execution + - shield_call + - memory_retrieval + description: Type of step being executed + step_id: + type: string + description: >- + Unique identifier for the step within a turn + step_details: + oneOf: + - $ref: '#/components/schemas/InferenceStep' + - $ref: '#/components/schemas/ToolExecutionStep' + - $ref: '#/components/schemas/ShieldCallStep' + - $ref: '#/components/schemas/MemoryRetrievalStep' + discriminator: + propertyName: step_type + mapping: + inference: '#/components/schemas/InferenceStep' + tool_execution: '#/components/schemas/ToolExecutionStep' + shield_call: '#/components/schemas/ShieldCallStep' + memory_retrieval: '#/components/schemas/MemoryRetrievalStep' + description: Complete details of the executed step + additionalProperties: false + required: + - event_type + - step_type + - step_id + - step_details + title: AgentTurnResponseStepCompletePayload + description: >- + Payload for step completion events in agent turn responses. + AgentTurnResponseStepProgressPayload: + type: object + properties: + event_type: + type: string + enum: + - step_start + - step_complete + - step_progress + - turn_start + - turn_complete + - turn_awaiting_input + const: step_progress + default: step_progress + description: Type of event being reported + step_type: + type: string + enum: + - inference + - tool_execution + - shield_call + - memory_retrieval + description: Type of step being executed + step_id: + type: string + description: >- + Unique identifier for the step within a turn + delta: + oneOf: + - $ref: '#/components/schemas/TextDelta' + - $ref: '#/components/schemas/ImageDelta' + - $ref: '#/components/schemas/ToolCallDelta' + discriminator: + propertyName: type + mapping: + text: '#/components/schemas/TextDelta' + image: '#/components/schemas/ImageDelta' + tool_call: '#/components/schemas/ToolCallDelta' + description: >- + Incremental content changes during step execution + additionalProperties: false + required: + - event_type + - step_type + - step_id + - delta + title: AgentTurnResponseStepProgressPayload + description: >- + Payload for step progress events in agent turn responses. + AgentTurnResponseStepStartPayload: + type: object + properties: + event_type: + type: string + enum: + - step_start + - step_complete + - step_progress + - turn_start + - turn_complete + - turn_awaiting_input + const: step_start + default: step_start + description: Type of event being reported + step_type: + type: string + enum: + - inference + - tool_execution + - shield_call + - memory_retrieval + description: Type of step being executed + step_id: + type: string + description: >- + Unique identifier for the step within a turn + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Additional metadata for the step + additionalProperties: false + required: + - event_type + - step_type + - step_id + title: AgentTurnResponseStepStartPayload + description: >- + Payload for step start events in agent turn responses. + AgentTurnResponseStreamChunk: + type: object + properties: + event: + $ref: '#/components/schemas/AgentTurnResponseEvent' + description: >- + Individual event in the agent turn response stream + additionalProperties: false + required: + - event + title: AgentTurnResponseStreamChunk + description: Streamed agent turn completion response. + "AgentTurnResponseTurnAwaitingInputPayload": + type: object + properties: + event_type: + type: string + enum: + - step_start + - step_complete + - step_progress + - turn_start + - turn_complete + - turn_awaiting_input + const: turn_awaiting_input + default: turn_awaiting_input + description: Type of event being reported + turn: + $ref: '#/components/schemas/Turn' + description: >- + Turn data when waiting for external tool responses + additionalProperties: false + required: + - event_type + - turn + title: >- + AgentTurnResponseTurnAwaitingInputPayload + description: >- + Payload for turn awaiting input events in agent turn responses. + AgentTurnResponseTurnCompletePayload: + type: object + properties: + event_type: + type: string + enum: + - step_start + - step_complete + - step_progress + - turn_start + - turn_complete + - turn_awaiting_input + const: turn_complete + default: turn_complete + description: Type of event being reported + turn: + $ref: '#/components/schemas/Turn' + description: >- + Complete turn data including all steps and results + additionalProperties: false + required: + - event_type + - turn + title: AgentTurnResponseTurnCompletePayload + description: >- + Payload for turn completion events in agent turn responses. + AgentTurnResponseTurnStartPayload: + type: object + properties: + event_type: + type: string + enum: + - step_start + - step_complete + - step_progress + - turn_start + - turn_complete + - turn_awaiting_input + const: turn_start + default: turn_start + description: Type of event being reported + turn_id: + type: string + description: >- + Unique identifier for the turn within a session + additionalProperties: false + required: + - event_type + - turn_id + title: AgentTurnResponseTurnStartPayload + description: >- + Payload for turn start events in agent turn responses. + ImageDelta: + type: object + properties: + type: + type: string + const: image + default: image + description: >- + Discriminator type of the delta. Always "image" + image: + type: string + contentEncoding: base64 + description: The incremental image data as bytes + additionalProperties: false + required: + - type + - image + title: ImageDelta + description: >- + An image content delta for streaming responses. + TextDelta: + type: object + properties: + type: + type: string + const: text + default: text + description: >- + Discriminator type of the delta. Always "text" + text: + type: string + description: The incremental text content + additionalProperties: false + required: + - type + - text + title: TextDelta + description: >- + A text content delta for streaming responses. + ToolCallDelta: + type: object + properties: + type: + type: string + const: tool_call + default: tool_call + description: >- + Discriminator type of the delta. Always "tool_call" + tool_call: + oneOf: + - type: string + - $ref: '#/components/schemas/ToolCall' + description: >- + Either an in-progress tool call string or the final parsed tool call + parse_status: + type: string + enum: + - started + - in_progress + - failed + - succeeded + description: Current parsing status of the tool call + additionalProperties: false + required: + - type + - tool_call + - parse_status + title: ToolCallDelta + description: >- + A tool call content delta for streaming responses. + ResumeAgentTurnRequest: + type: object + properties: + tool_responses: + type: array + items: + $ref: '#/components/schemas/ToolResponse' + description: >- + The tool call responses to resume the turn with. + stream: + type: boolean + description: Whether to stream the response. + additionalProperties: false + required: + - tool_responses + title: ResumeAgentTurnRequest + AgentStepResponse: + type: object + properties: + step: + oneOf: + - $ref: '#/components/schemas/InferenceStep' + - $ref: '#/components/schemas/ToolExecutionStep' + - $ref: '#/components/schemas/ShieldCallStep' + - $ref: '#/components/schemas/MemoryRetrievalStep' + discriminator: + propertyName: step_type + mapping: + inference: '#/components/schemas/InferenceStep' + tool_execution: '#/components/schemas/ToolExecutionStep' + shield_call: '#/components/schemas/ShieldCallStep' + memory_retrieval: '#/components/schemas/MemoryRetrievalStep' + description: >- + The complete step data and execution details + additionalProperties: false + required: + - step + title: AgentStepResponse + description: >- + Response containing details of a specific agent step. + Benchmark: + type: object + properties: + identifier: + type: string + provider_resource_id: + type: string + provider_id: + type: string + type: + type: string + enum: + - model + - shield + - vector_store + - dataset + - scoring_function + - benchmark + - tool + - tool_group + - prompt + const: benchmark + default: benchmark + description: The resource type, always benchmark + dataset_id: + type: string + description: >- + Identifier of the dataset to use for the benchmark evaluation + scoring_functions: + type: array + items: + type: string + description: >- + List of scoring function identifiers to apply during evaluation + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: Metadata for this evaluation task + additionalProperties: false + required: + - identifier + - provider_id + - type + - dataset_id + - scoring_functions + - metadata + title: Benchmark + description: >- + A benchmark resource for evaluating model performance. + ListBenchmarksResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/Benchmark' + additionalProperties: false + required: + - data + title: ListBenchmarksResponse + RegisterBenchmarkRequest: + type: object + properties: + benchmark_id: + type: string + description: The ID of the benchmark to register. + dataset_id: + type: string + description: >- + The ID of the dataset to use for the benchmark. + scoring_functions: + type: array + items: + type: string + description: >- + The scoring functions to use for the benchmark. + provider_benchmark_id: + type: string + description: >- + The ID of the provider benchmark to use for the benchmark. + provider_id: + type: string + description: >- + The ID of the provider to use for the benchmark. + metadata: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The metadata to use for the benchmark. + additionalProperties: false + required: + - benchmark_id + - dataset_id + - scoring_functions + title: RegisterBenchmarkRequest + AgentCandidate: + type: object + properties: + type: + type: string + const: agent + default: agent + config: + $ref: '#/components/schemas/AgentConfig' + description: >- + The configuration for the agent candidate. + additionalProperties: false + required: + - type + - config + title: AgentCandidate + description: An agent candidate for evaluation. + BenchmarkConfig: + type: object + properties: + eval_candidate: + oneOf: + - $ref: '#/components/schemas/ModelCandidate' + - $ref: '#/components/schemas/AgentCandidate' + discriminator: + propertyName: type + mapping: + model: '#/components/schemas/ModelCandidate' + agent: '#/components/schemas/AgentCandidate' + description: The candidate to evaluate. + scoring_params: + type: object + additionalProperties: + $ref: '#/components/schemas/ScoringFnParams' + description: >- + Map between scoring function id and parameters for each scoring function + you want to run + num_examples: + type: integer + description: >- + (Optional) The number of examples to evaluate. If not provided, all examples + in the dataset will be evaluated + additionalProperties: false + required: + - eval_candidate + - scoring_params + title: BenchmarkConfig + description: >- + A benchmark configuration for evaluation. + ModelCandidate: + type: object + properties: + type: + type: string + const: model + default: model + model: + type: string + description: The model ID to evaluate. + sampling_params: + $ref: '#/components/schemas/SamplingParams' + description: The sampling parameters for the model. + system_message: + $ref: '#/components/schemas/SystemMessage' + description: >- + (Optional) The system message providing instructions or context to the + model. + additionalProperties: false + required: + - type + - model + - sampling_params + title: ModelCandidate + description: A model candidate for evaluation. + EvaluateRowsRequest: + type: object + properties: + input_rows: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The rows to evaluate. + scoring_functions: + type: array + items: + type: string + description: >- + The scoring functions to use for the evaluation. + benchmark_config: + $ref: '#/components/schemas/BenchmarkConfig' + description: The configuration for the benchmark. + additionalProperties: false + required: + - input_rows + - scoring_functions + - benchmark_config + title: EvaluateRowsRequest + EvaluateResponse: + type: object + properties: + generations: + type: array + items: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The generations from the evaluation. + scores: + type: object + additionalProperties: + $ref: '#/components/schemas/ScoringResult' + description: The scores from the evaluation. + additionalProperties: false + required: + - generations + - scores + title: EvaluateResponse + description: The response from an evaluation. + RunEvalRequest: + type: object + properties: + benchmark_config: + $ref: '#/components/schemas/BenchmarkConfig' + description: The configuration for the benchmark. + additionalProperties: false + required: + - benchmark_config + title: RunEvalRequest + Job: + type: object + properties: + job_id: + type: string + description: Unique identifier for the job + status: + type: string + enum: + - completed + - in_progress + - failed + - scheduled + - cancelled + description: Current execution status of the job + additionalProperties: false + required: + - job_id + - status + title: Job + description: >- + A job execution instance with status tracking. + RerankRequest: + type: object + properties: + model: + type: string + description: >- + The identifier of the reranking model to use. + query: + oneOf: + - type: string + - $ref: '#/components/schemas/OpenAIChatCompletionContentPartTextParam' + - $ref: '#/components/schemas/OpenAIChatCompletionContentPartImageParam' + description: >- + The search query to rank items against. Can be a string, text content + part, or image content part. The input must not exceed the model's max + input token length. + items: + type: array + items: + oneOf: + - type: string + - $ref: '#/components/schemas/OpenAIChatCompletionContentPartTextParam' + - $ref: '#/components/schemas/OpenAIChatCompletionContentPartImageParam' + description: >- + List of items to rerank. Each item can be a string, text content part, + or image content part. Each input must not exceed the model's max input + token length. + max_num_results: + type: integer + description: >- + (Optional) Maximum number of results to return. Default: returns all. + additionalProperties: false + required: + - model + - query + - items + title: RerankRequest + RerankData: + type: object + properties: + index: + type: integer + description: >- + The original index of the document in the input list + relevance_score: + type: number + description: >- + The relevance score from the model output. Values are inverted when applicable + so that higher scores indicate greater relevance. + additionalProperties: false + required: + - index + - relevance_score + title: RerankData + description: >- + A single rerank result from a reranking response. + RerankResponse: + type: object + properties: + data: + type: array + items: + $ref: '#/components/schemas/RerankData' + description: >- + List of rerank result objects, sorted by relevance score (descending) + additionalProperties: false + required: + - data + title: RerankResponse + description: Response from a reranking request. + Checkpoint: + type: object + properties: + identifier: + type: string + description: Unique identifier for the checkpoint + created_at: + type: string + format: date-time + description: >- + Timestamp when the checkpoint was created + epoch: + type: integer + description: >- + Training epoch when the checkpoint was saved + post_training_job_id: + type: string + description: >- + Identifier of the training job that created this checkpoint + path: + type: string + description: >- + File system path where the checkpoint is stored + training_metrics: + $ref: '#/components/schemas/PostTrainingMetric' + description: >- + (Optional) Training metrics associated with this checkpoint + additionalProperties: false + required: + - identifier + - created_at + - epoch + - post_training_job_id + - path + title: Checkpoint + description: Checkpoint created during training runs. + PostTrainingJobArtifactsResponse: + type: object + properties: + job_uuid: + type: string + description: Unique identifier for the training job + checkpoints: + type: array + items: + $ref: '#/components/schemas/Checkpoint' + description: >- + List of model checkpoints created during training + additionalProperties: false + required: + - job_uuid + - checkpoints + title: PostTrainingJobArtifactsResponse + description: Artifacts of a finetuning job. + PostTrainingMetric: + type: object + properties: + epoch: + type: integer + description: Training epoch number + train_loss: + type: number + description: Loss value on the training dataset + validation_loss: + type: number + description: Loss value on the validation dataset + perplexity: + type: number + description: >- + Perplexity metric indicating model confidence + additionalProperties: false + required: + - epoch + - train_loss + - validation_loss + - perplexity + title: PostTrainingMetric + description: >- + Training metrics captured during post-training jobs. + CancelTrainingJobRequest: + type: object + properties: + job_uuid: + type: string + description: The UUID of the job to cancel. + additionalProperties: false + required: + - job_uuid + title: CancelTrainingJobRequest + PostTrainingJobStatusResponse: + type: object + properties: + job_uuid: + type: string + description: Unique identifier for the training job + status: + type: string + enum: + - completed + - in_progress + - failed + - scheduled + - cancelled + description: Current status of the training job + scheduled_at: + type: string + format: date-time + description: >- + (Optional) Timestamp when the job was scheduled + started_at: + type: string + format: date-time + description: >- + (Optional) Timestamp when the job execution began + completed_at: + type: string + format: date-time + description: >- + (Optional) Timestamp when the job finished, if completed + resources_allocated: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: >- + (Optional) Information about computational resources allocated to the + job + checkpoints: + type: array + items: + $ref: '#/components/schemas/Checkpoint' + description: >- + List of model checkpoints created during training + additionalProperties: false + required: + - job_uuid + - status + - checkpoints + title: PostTrainingJobStatusResponse + description: Status of a finetuning job. + ListPostTrainingJobsResponse: + type: object + properties: + data: + type: array + items: + type: object + properties: + job_uuid: + type: string + additionalProperties: false + required: + - job_uuid + title: PostTrainingJob + additionalProperties: false + required: + - data + title: ListPostTrainingJobsResponse + DPOAlignmentConfig: + type: object + properties: + beta: + type: number + description: Temperature parameter for the DPO loss + loss_type: + $ref: '#/components/schemas/DPOLossType' + default: sigmoid + description: The type of loss function to use for DPO + additionalProperties: false + required: + - beta + - loss_type + title: DPOAlignmentConfig + description: >- + Configuration for Direct Preference Optimization (DPO) alignment. + DPOLossType: + type: string + enum: + - sigmoid + - hinge + - ipo + - kto_pair + title: DPOLossType + DataConfig: + type: object + properties: + dataset_id: + type: string + description: >- + Unique identifier for the training dataset + batch_size: + type: integer + description: Number of samples per training batch + shuffle: + type: boolean + description: >- + Whether to shuffle the dataset during training + data_format: + $ref: '#/components/schemas/DatasetFormat' + description: >- + Format of the dataset (instruct or dialog) + validation_dataset_id: + type: string + description: >- + (Optional) Unique identifier for the validation dataset + packed: + type: boolean + default: false + description: >- + (Optional) Whether to pack multiple samples into a single sequence for + efficiency + train_on_input: + type: boolean + default: false + description: >- + (Optional) Whether to compute loss on input tokens as well as output tokens + additionalProperties: false + required: + - dataset_id + - batch_size + - shuffle + - data_format + title: DataConfig + description: >- + Configuration for training data and data loading. + DatasetFormat: + type: string + enum: + - instruct + - dialog + title: DatasetFormat + description: Format of the training dataset. + EfficiencyConfig: + type: object + properties: + enable_activation_checkpointing: + type: boolean + default: false + description: >- + (Optional) Whether to use activation checkpointing to reduce memory usage + enable_activation_offloading: + type: boolean + default: false + description: >- + (Optional) Whether to offload activations to CPU to save GPU memory + memory_efficient_fsdp_wrap: + type: boolean + default: false + description: >- + (Optional) Whether to use memory-efficient FSDP wrapping + fsdp_cpu_offload: + type: boolean + default: false + description: >- + (Optional) Whether to offload FSDP parameters to CPU + additionalProperties: false + title: EfficiencyConfig + description: >- + Configuration for memory and compute efficiency optimizations. + OptimizerConfig: + type: object + properties: + optimizer_type: + $ref: '#/components/schemas/OptimizerType' + description: >- + Type of optimizer to use (adam, adamw, or sgd) + lr: + type: number + description: Learning rate for the optimizer + weight_decay: + type: number + description: >- + Weight decay coefficient for regularization + num_warmup_steps: + type: integer + description: Number of steps for learning rate warmup + additionalProperties: false + required: + - optimizer_type + - lr + - weight_decay + - num_warmup_steps + title: OptimizerConfig + description: >- + Configuration parameters for the optimization algorithm. + OptimizerType: + type: string + enum: + - adam + - adamw + - sgd + title: OptimizerType + description: >- + Available optimizer algorithms for training. + TrainingConfig: + type: object + properties: + n_epochs: + type: integer + description: Number of training epochs to run + max_steps_per_epoch: + type: integer + default: 1 + description: Maximum number of steps to run per epoch + gradient_accumulation_steps: + type: integer + default: 1 + description: >- + Number of steps to accumulate gradients before updating + max_validation_steps: + type: integer + default: 1 + description: >- + (Optional) Maximum number of validation steps per epoch + data_config: + $ref: '#/components/schemas/DataConfig' + description: >- + (Optional) Configuration for data loading and formatting + optimizer_config: + $ref: '#/components/schemas/OptimizerConfig' + description: >- + (Optional) Configuration for the optimization algorithm + efficiency_config: + $ref: '#/components/schemas/EfficiencyConfig' + description: >- + (Optional) Configuration for memory and compute optimizations + dtype: + type: string + default: bf16 + description: >- + (Optional) Data type for model parameters (bf16, fp16, fp32) + additionalProperties: false + required: + - n_epochs + - max_steps_per_epoch + - gradient_accumulation_steps + title: TrainingConfig + description: >- + Comprehensive configuration for the training process. + PreferenceOptimizeRequest: + type: object + properties: + job_uuid: + type: string + description: The UUID of the job to create. + finetuned_model: + type: string + description: The model to fine-tune. + algorithm_config: + $ref: '#/components/schemas/DPOAlignmentConfig' + description: The algorithm configuration. + training_config: + $ref: '#/components/schemas/TrainingConfig' + description: The training configuration. + hyperparam_search_config: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The hyperparam search configuration. + logger_config: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The logger configuration. + additionalProperties: false + required: + - job_uuid + - finetuned_model + - algorithm_config + - training_config + - hyperparam_search_config + - logger_config + title: PreferenceOptimizeRequest + PostTrainingJob: + type: object + properties: + job_uuid: + type: string + additionalProperties: false + required: + - job_uuid + title: PostTrainingJob + AlgorithmConfig: + oneOf: + - $ref: '#/components/schemas/LoraFinetuningConfig' + - $ref: '#/components/schemas/QATFinetuningConfig' + discriminator: + propertyName: type + mapping: + LoRA: '#/components/schemas/LoraFinetuningConfig' + QAT: '#/components/schemas/QATFinetuningConfig' + LoraFinetuningConfig: + type: object + properties: + type: + type: string + const: LoRA + default: LoRA + description: Algorithm type identifier, always "LoRA" + lora_attn_modules: + type: array + items: + type: string + description: >- + List of attention module names to apply LoRA to + apply_lora_to_mlp: + type: boolean + description: Whether to apply LoRA to MLP layers + apply_lora_to_output: + type: boolean + description: >- + Whether to apply LoRA to output projection layers + rank: + type: integer + description: >- + Rank of the LoRA adaptation (lower rank = fewer parameters) + alpha: + type: integer + description: >- + LoRA scaling parameter that controls adaptation strength + use_dora: + type: boolean + default: false + description: >- + (Optional) Whether to use DoRA (Weight-Decomposed Low-Rank Adaptation) + quantize_base: + type: boolean + default: false + description: >- + (Optional) Whether to quantize the base model weights + additionalProperties: false + required: + - type + - lora_attn_modules + - apply_lora_to_mlp + - apply_lora_to_output + - rank + - alpha + title: LoraFinetuningConfig + description: >- + Configuration for Low-Rank Adaptation (LoRA) fine-tuning. + QATFinetuningConfig: + type: object + properties: + type: + type: string + const: QAT + default: QAT + description: Algorithm type identifier, always "QAT" + quantizer_name: + type: string + description: >- + Name of the quantization algorithm to use + group_size: + type: integer + description: Size of groups for grouped quantization + additionalProperties: false + required: + - type + - quantizer_name + - group_size + title: QATFinetuningConfig + description: >- + Configuration for Quantization-Aware Training (QAT) fine-tuning. + SupervisedFineTuneRequest: + type: object + properties: + job_uuid: + type: string + description: The UUID of the job to create. + training_config: + $ref: '#/components/schemas/TrainingConfig' + description: The training configuration. + hyperparam_search_config: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The hyperparam search configuration. + logger_config: + type: object + additionalProperties: + oneOf: + - type: 'null' + - type: boolean + - type: number + - type: string + - type: array + - type: object + description: The logger configuration. + model: + type: string + description: The model to fine-tune. + checkpoint_dir: + type: string + description: The directory to save checkpoint(s) to. + algorithm_config: + $ref: '#/components/schemas/AlgorithmConfig' + description: The algorithm configuration. + additionalProperties: false + required: + - job_uuid + - training_config + - hyperparam_search_config + - logger_config + title: SupervisedFineTuneRequest + responses: + BadRequest400: + description: The request was invalid or malformed + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + status: 400 + title: Bad Request + detail: The request was invalid or malformed + TooManyRequests429: + description: >- + The client has sent too many requests in a given amount of time + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + status: 429 + title: Too Many Requests + detail: >- + You have exceeded the rate limit. Please try again later. + InternalServerError500: + description: >- + The server encountered an unexpected error + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + status: 500 + title: Internal Server Error + detail: >- + An unexpected error occurred. Our team has been notified. + DefaultError: + description: An unexpected error occurred + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + example: + status: 0 + title: Error + detail: An unexpected error occurred +security: + - Default: [] +tags: + - name: Agents + description: >- + APIs for creating and interacting with agentic systems. + x-displayName: Agents + - name: Benchmarks + description: '' + - name: Conversations + description: >- + Protocol for conversation management operations. + x-displayName: Conversations + - name: DatasetIO + description: '' + - name: Datasets + description: '' + - name: Eval + description: >- + Llama Stack Evaluation API for running evaluations on model and agent candidates. + x-displayName: Evaluations + - name: Files + description: >- + This API is used to upload documents that can be used with other Llama Stack + APIs. + x-displayName: Files + - name: Inference + description: >- + Llama Stack Inference API for generating completions, chat completions, and + embeddings. + + + This API provides the raw interface to the underlying models. Two kinds of models + are supported: + + - LLM models: these models generate "raw" and "chat" (conversational) completions. + + - Embedding models: these models generate embeddings to be used for semantic + search. + x-displayName: Inference + - name: Inspect + description: >- + APIs for inspecting the Llama Stack service, including health status, available + API routes with methods and implementing providers. + x-displayName: Inspect + - name: Models + description: '' + - name: PostTraining (Coming Soon) + description: '' + - name: Prompts + description: >- + Protocol for prompt management operations. + x-displayName: Prompts + - name: Providers + description: >- + Providers API for inspecting, listing, and modifying providers and their configurations. + x-displayName: Providers + - name: Safety + description: OpenAI-compatible Moderations API. + x-displayName: Safety + - name: Scoring + description: '' + - name: ScoringFunctions + description: '' + - name: Shields + description: '' + - name: SyntheticDataGeneration (Coming Soon) + description: '' + - name: ToolGroups + description: '' + - name: ToolRuntime + description: '' + - name: VectorIO + description: '' +x-tagGroups: + - name: Operations + tags: + - Agents + - Benchmarks + - Conversations + - DatasetIO + - Datasets + - Eval + - Files + - Inference + - Inspect + - Models + - PostTraining (Coming Soon) + - Prompts + - Providers + - Safety + - Scoring + - ScoringFunctions + - Shields + - SyntheticDataGeneration (Coming Soon) + - ToolGroups + - ToolRuntime + - VectorIO diff --git a/containers/Containerfile b/containers/Containerfile index c6e47fa1d..1ddf102af 100644 --- a/containers/Containerfile +++ b/containers/Containerfile @@ -60,6 +60,17 @@ ENV RUN_CONFIG_PATH=${RUN_CONFIG_PATH} # Copy the repository so editable installs and run configurations are available. COPY . /workspace +# Install the client package if it is provided +# NOTE: this is installed before llama-stack since llama-stack depends on llama-stack-client-python +RUN set -eux; \ + if [ -n "$LLAMA_STACK_CLIENT_DIR" ]; then \ + if [ ! -d "$LLAMA_STACK_CLIENT_DIR" ]; then \ + echo "LLAMA_STACK_CLIENT_DIR is set but $LLAMA_STACK_CLIENT_DIR does not exist" >&2; \ + exit 1; \ + fi; \ + uv pip install --no-cache-dir -e "$LLAMA_STACK_CLIENT_DIR"; \ + fi; + # Install llama-stack RUN set -eux; \ if [ "$INSTALL_MODE" = "editable" ]; then \ @@ -83,16 +94,6 @@ RUN set -eux; \ fi; \ fi; -# Install the client package if it is provided -RUN set -eux; \ - if [ -n "$LLAMA_STACK_CLIENT_DIR" ]; then \ - if [ ! -d "$LLAMA_STACK_CLIENT_DIR" ]; then \ - echo "LLAMA_STACK_CLIENT_DIR is set but $LLAMA_STACK_CLIENT_DIR does not exist" >&2; \ - exit 1; \ - fi; \ - uv pip install --no-cache-dir -e "$LLAMA_STACK_CLIENT_DIR"; \ - fi; - # Install the dependencies for the distribution RUN set -eux; \ if [ -z "$DISTRO_NAME" ]; then \ diff --git a/docs/docs/building_applications/rag.mdx b/docs/docs/building_applications/rag.mdx index 8307448be..b1681dc62 100644 --- a/docs/docs/building_applications/rag.mdx +++ b/docs/docs/building_applications/rag.mdx @@ -88,18 +88,19 @@ Llama Stack provides OpenAI-compatible RAG capabilities through: To enable automatic vector store creation without specifying embedding models, configure a default embedding model in your run.yaml like so: ```yaml -models: - - model_id: nomic-ai/nomic-embed-text-v1.5 - provider_id: inline::sentence-transformers - metadata: - embedding_dimension: 768 - default_configured: true +vector_stores: + default_provider_id: faiss + default_embedding_model: + provider_id: sentence-transformers + model_id: nomic-ai/nomic-embed-text-v1.5 ``` With this configuration: -- `client.vector_stores.create()` works without requiring embedding model parameters -- The system automatically uses the default model and its embedding dimension for any newly created vector store -- Only one model can be marked as `default_configured: true` +- `client.vector_stores.create()` works without requiring embedding model or provider parameters +- The system automatically uses the default vector store provider (`faiss`) when multiple providers are available +- The system automatically uses the default embedding model (`sentence-transformers/nomic-ai/nomic-embed-text-v1.5`) for any newly created vector store +- The `default_provider_id` specifies which vector storage backend to use +- The `default_embedding_model` specifies both the inference provider and model for embeddings ## Vector Store Operations @@ -108,14 +109,15 @@ With this configuration: You can create vector stores with automatic or explicit embedding model selection: ```python -# Automatic - uses default configured embedding model +# Automatic - uses default configured embedding model and vector store provider vs = client.vector_stores.create() -# Explicit - specify embedding model when you need a specific one +# Explicit - specify embedding model and/or provider when you need specific ones vs = client.vector_stores.create( extra_body={ - "embedding_model": "nomic-ai/nomic-embed-text-v1.5", - "embedding_dimension": 768 + "provider_id": "faiss", # Optional: specify vector store provider + "embedding_model": "sentence-transformers/nomic-ai/nomic-embed-text-v1.5", + "embedding_dimension": 768 # Optional: will be auto-detected if not provided } ) ``` diff --git a/docs/docs/distributions/building_distro.mdx b/docs/docs/distributions/building_distro.mdx index 0c40613d6..c4a01bf7d 100644 --- a/docs/docs/distributions/building_distro.mdx +++ b/docs/docs/distributions/building_distro.mdx @@ -19,6 +19,7 @@ Browse that folder to understand available providers and copy a distribution to import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; + diff --git a/docs/docs/distributions/configuration.mdx b/docs/docs/distributions/configuration.mdx index 81243c97b..bf3156865 100644 --- a/docs/docs/distributions/configuration.mdx +++ b/docs/docs/distributions/configuration.mdx @@ -44,18 +44,32 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - namespace: null - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ollama}/agents_store.db + persistence: + agent_state: + backend: kv_default + namespace: agents + responses: + backend: sql_default + table_name: responses telemetry: - provider_id: meta-reference provider_type: inline::meta-reference config: {} -metadata_store: - namespace: null - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ollama}/registry.db +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ollama}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ollama}/sqlstore.db + references: + metadata: + backend: kv_default + namespace: registry + inference: + backend: sql_default + table_name: inference_store models: - metadata: {} model_id: ${env.INFERENCE_MODEL} diff --git a/docs/docs/distributions/k8s/stack-configmap.yaml b/docs/docs/distributions/k8s/stack-configmap.yaml index 3dbb0da97..c71ab05d8 100644 --- a/docs/docs/distributions/k8s/stack-configmap.yaml +++ b/docs/docs/distributions/k8s/stack-configmap.yaml @@ -1,56 +1,155 @@ apiVersion: v1 data: - stack_run_config.yaml: "version: '2'\nimage_name: kubernetes-demo\napis:\n- agents\n- - inference\n- files\n- safety\n- telemetry\n- tool_runtime\n- vector_io\nproviders:\n - \ inference:\n - provider_id: vllm-inference\n provider_type: remote::vllm\n - \ config:\n url: ${env.VLLM_URL:=http://localhost:8000/v1}\n max_tokens: - ${env.VLLM_MAX_TOKENS:=4096}\n api_token: ${env.VLLM_API_TOKEN:=fake}\n tls_verify: - ${env.VLLM_TLS_VERIFY:=true}\n - provider_id: vllm-safety\n provider_type: - remote::vllm\n config:\n url: ${env.VLLM_SAFETY_URL:=http://localhost:8000/v1}\n - \ max_tokens: ${env.VLLM_MAX_TOKENS:=4096}\n api_token: ${env.VLLM_API_TOKEN:=fake}\n - \ tls_verify: ${env.VLLM_TLS_VERIFY:=true}\n - provider_id: sentence-transformers\n - \ provider_type: inline::sentence-transformers\n config: {}\n vector_io:\n - \ - provider_id: ${env.ENABLE_CHROMADB:+chromadb}\n provider_type: remote::chromadb\n - \ config:\n url: ${env.CHROMADB_URL:=}\n kvstore:\n type: postgres\n - \ host: ${env.POSTGRES_HOST:=localhost}\n port: ${env.POSTGRES_PORT:=5432}\n - \ db: ${env.POSTGRES_DB:=llamastack}\n user: ${env.POSTGRES_USER:=llamastack}\n - \ password: ${env.POSTGRES_PASSWORD:=llamastack}\n files:\n - provider_id: - meta-reference-files\n provider_type: inline::localfs\n config:\n storage_dir: - ${env.FILES_STORAGE_DIR:=~/.llama/distributions/starter/files}\n metadata_store:\n - \ type: sqlite\n db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/files_metadata.db - \ \n safety:\n - provider_id: llama-guard\n provider_type: inline::llama-guard\n - \ config:\n excluded_categories: []\n agents:\n - provider_id: meta-reference\n - \ provider_type: inline::meta-reference\n config:\n persistence_store:\n - \ type: postgres\n host: ${env.POSTGRES_HOST:=localhost}\n port: - ${env.POSTGRES_PORT:=5432}\n db: ${env.POSTGRES_DB:=llamastack}\n user: - ${env.POSTGRES_USER:=llamastack}\n password: ${env.POSTGRES_PASSWORD:=llamastack}\n - \ responses_store:\n type: postgres\n host: ${env.POSTGRES_HOST:=localhost}\n - \ port: ${env.POSTGRES_PORT:=5432}\n db: ${env.POSTGRES_DB:=llamastack}\n - \ user: ${env.POSTGRES_USER:=llamastack}\n password: ${env.POSTGRES_PASSWORD:=llamastack}\n - \ telemetry:\n - provider_id: meta-reference\n provider_type: inline::meta-reference\n - \ config:\n service_name: \"${env.OTEL_SERVICE_NAME:=\\u200B}\"\n sinks: - ${env.TELEMETRY_SINKS:=console}\n tool_runtime:\n - provider_id: brave-search\n - \ provider_type: remote::brave-search\n config:\n api_key: ${env.BRAVE_SEARCH_API_KEY:+}\n - \ max_results: 3\n - provider_id: tavily-search\n provider_type: remote::tavily-search\n - \ config:\n api_key: ${env.TAVILY_SEARCH_API_KEY:+}\n max_results: - 3\n - provider_id: rag-runtime\n provider_type: inline::rag-runtime\n config: - {}\n - provider_id: model-context-protocol\n provider_type: remote::model-context-protocol\n - \ config: {}\nmetadata_store:\n type: postgres\n host: ${env.POSTGRES_HOST:=localhost}\n - \ port: ${env.POSTGRES_PORT:=5432}\n db: ${env.POSTGRES_DB:=llamastack}\n user: - ${env.POSTGRES_USER:=llamastack}\n password: ${env.POSTGRES_PASSWORD:=llamastack}\n - \ table_name: llamastack_kvstore\ninference_store:\n type: postgres\n host: - ${env.POSTGRES_HOST:=localhost}\n port: ${env.POSTGRES_PORT:=5432}\n db: ${env.POSTGRES_DB:=llamastack}\n - \ user: ${env.POSTGRES_USER:=llamastack}\n password: ${env.POSTGRES_PASSWORD:=llamastack}\nmodels:\n- - metadata:\n embedding_dimension: 384\n model_id: all-MiniLM-L6-v2\n provider_id: - sentence-transformers\n model_type: embedding\n- metadata: {}\n model_id: ${env.INFERENCE_MODEL}\n - \ provider_id: vllm-inference\n model_type: llm\n- metadata: {}\n model_id: - ${env.SAFETY_MODEL:=meta-llama/Llama-Guard-3-1B}\n provider_id: vllm-safety\n - \ model_type: llm\nshields:\n- shield_id: ${env.SAFETY_MODEL:=meta-llama/Llama-Guard-3-1B}\nvector_dbs: - []\ndatasets: []\nscoring_fns: []\nbenchmarks: []\ntool_groups:\n- toolgroup_id: - builtin::websearch\n provider_id: tavily-search\n- toolgroup_id: builtin::rag\n - \ provider_id: rag-runtime\nserver:\n port: 8321\n auth:\n provider_config:\n - \ type: github_token\n" + stack_run_config.yaml: | + version: '2' + image_name: kubernetes-demo + apis: + - agents + - inference + - files + - safety + - telemetry + - tool_runtime + - vector_io + providers: + inference: + - provider_id: vllm-inference + provider_type: remote::vllm + config: + url: ${env.VLLM_URL:=http://localhost:8000/v1} + max_tokens: ${env.VLLM_MAX_TOKENS:=4096} + api_token: ${env.VLLM_API_TOKEN:=fake} + tls_verify: ${env.VLLM_TLS_VERIFY:=true} + - provider_id: vllm-safety + provider_type: remote::vllm + config: + url: ${env.VLLM_SAFETY_URL:=http://localhost:8000/v1} + max_tokens: ${env.VLLM_MAX_TOKENS:=4096} + api_token: ${env.VLLM_API_TOKEN:=fake} + tls_verify: ${env.VLLM_TLS_VERIFY:=true} + - provider_id: sentence-transformers + provider_type: inline::sentence-transformers + config: {} + vector_io: + - provider_id: ${env.ENABLE_CHROMADB:+chromadb} + provider_type: remote::chromadb + config: + url: ${env.CHROMADB_URL:=} + kvstore: + type: postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + files: + - provider_id: meta-reference-files + provider_type: inline::localfs + config: + storage_dir: ${env.FILES_STORAGE_DIR:=~/.llama/distributions/starter/files} + metadata_store: + type: sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/files_metadata.db + safety: + - provider_id: llama-guard + provider_type: inline::llama-guard + config: + excluded_categories: [] + agents: + - provider_id: meta-reference + provider_type: inline::meta-reference + config: + persistence_store: + type: postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + responses_store: + type: postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + telemetry: + - provider_id: meta-reference + provider_type: inline::meta-reference + config: + service_name: "${env.OTEL_SERVICE_NAME:=\u200B}" + sinks: ${env.TELEMETRY_SINKS:=console} + tool_runtime: + - provider_id: brave-search + provider_type: remote::brave-search + config: + api_key: ${env.BRAVE_SEARCH_API_KEY:+} + max_results: 3 + - provider_id: tavily-search + provider_type: remote::tavily-search + config: + api_key: ${env.TAVILY_SEARCH_API_KEY:+} + max_results: 3 + - provider_id: rag-runtime + provider_type: inline::rag-runtime + config: {} + - provider_id: model-context-protocol + provider_type: remote::model-context-protocol + config: {} + storage: + backends: + kv_default: + type: kv_postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + table_name: ${env.POSTGRES_TABLE_NAME:=llamastack_kvstore} + sql_default: + type: sql_postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + references: + metadata: + backend: kv_default + namespace: registry + inference: + backend: sql_default + table_name: inference_store + models: + - metadata: + embedding_dimension: 768 + model_id: nomic-embed-text-v1.5 + provider_id: sentence-transformers + model_type: embedding + - metadata: {} + model_id: ${env.INFERENCE_MODEL} + provider_id: vllm-inference + model_type: llm + - metadata: {} + model_id: ${env.SAFETY_MODEL:=meta-llama/Llama-Guard-3-1B} + provider_id: vllm-safety + model_type: llm + shields: + - shield_id: ${env.SAFETY_MODEL:=meta-llama/Llama-Guard-3-1B} + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: tavily-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime + server: + port: 8321 + auth: + provider_config: + type: github_token kind: ConfigMap metadata: - creationTimestamp: null name: llama-stack-config diff --git a/docs/docs/distributions/k8s/stack_run_config.yaml b/docs/docs/distributions/k8s/stack_run_config.yaml index ee28a1ea8..863565fdf 100644 --- a/docs/docs/distributions/k8s/stack_run_config.yaml +++ b/docs/docs/distributions/k8s/stack_run_config.yaml @@ -93,21 +93,30 @@ providers: - provider_id: model-context-protocol provider_type: remote::model-context-protocol config: {} -metadata_store: - type: postgres - host: ${env.POSTGRES_HOST:=localhost} - port: ${env.POSTGRES_PORT:=5432} - db: ${env.POSTGRES_DB:=llamastack} - user: ${env.POSTGRES_USER:=llamastack} - password: ${env.POSTGRES_PASSWORD:=llamastack} - table_name: llamastack_kvstore -inference_store: - type: postgres - host: ${env.POSTGRES_HOST:=localhost} - port: ${env.POSTGRES_PORT:=5432} - db: ${env.POSTGRES_DB:=llamastack} - user: ${env.POSTGRES_USER:=llamastack} - password: ${env.POSTGRES_PASSWORD:=llamastack} +storage: + backends: + kv_default: + type: kv_postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + table_name: ${env.POSTGRES_TABLE_NAME:=llamastack_kvstore} + sql_default: + type: sql_postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + references: + metadata: + backend: kv_default + namespace: registry + inference: + backend: sql_default + table_name: inference_store models: - metadata: embedding_dimension: 768 diff --git a/docs/docs/providers/agents/inline_meta-reference.mdx b/docs/docs/providers/agents/inline_meta-reference.mdx index fd961745f..fac9b8406 100644 --- a/docs/docs/providers/agents/inline_meta-reference.mdx +++ b/docs/docs/providers/agents/inline_meta-reference.mdx @@ -14,16 +14,18 @@ Meta's reference implementation of an agent system that can use tools, access ve | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `persistence_store` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | | -| `responses_store` | `utils.sqlstore.sqlstore.SqliteSqlStoreConfig \| utils.sqlstore.sqlstore.PostgresSqlStoreConfig` | No | sqlite | | +| `persistence` | `` | No | | | ## Sample Configuration ```yaml -persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/agents_store.db -responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/responses_store.db +persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 ``` diff --git a/docs/docs/providers/batches/inline_reference.mdx b/docs/docs/providers/batches/inline_reference.mdx index f43800555..45304fbb1 100644 --- a/docs/docs/providers/batches/inline_reference.mdx +++ b/docs/docs/providers/batches/inline_reference.mdx @@ -14,7 +14,7 @@ Reference implementation of batches API with KVStore persistence. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | Configuration for the key-value store backend. | +| `kvstore` | `` | No | | Configuration for the key-value store backend. | | `max_concurrent_batches` | `` | No | 1 | Maximum number of concurrent batches to process simultaneously. | | `max_concurrent_requests_per_batch` | `` | No | 10 | Maximum number of concurrent requests to process per batch. | @@ -22,6 +22,6 @@ Reference implementation of batches API with KVStore persistence. ```yaml kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/batches.db + namespace: batches + backend: kv_default ``` diff --git a/docs/docs/providers/datasetio/inline_localfs.mdx b/docs/docs/providers/datasetio/inline_localfs.mdx index b02a3a3bd..a9363376c 100644 --- a/docs/docs/providers/datasetio/inline_localfs.mdx +++ b/docs/docs/providers/datasetio/inline_localfs.mdx @@ -14,12 +14,12 @@ Local filesystem-based dataset I/O provider for reading and writing datasets to | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | | +| `kvstore` | `` | No | | | ## Sample Configuration ```yaml kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default ``` diff --git a/docs/docs/providers/datasetio/remote_huggingface.mdx b/docs/docs/providers/datasetio/remote_huggingface.mdx index 82597d999..de3ffaaa6 100644 --- a/docs/docs/providers/datasetio/remote_huggingface.mdx +++ b/docs/docs/providers/datasetio/remote_huggingface.mdx @@ -14,12 +14,12 @@ HuggingFace datasets provider for accessing and managing datasets from the Huggi | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | | +| `kvstore` | `` | No | | | ## Sample Configuration ```yaml kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/huggingface_datasetio.db + namespace: datasetio::huggingface + backend: kv_default ``` diff --git a/docs/docs/providers/eval/inline_meta-reference.mdx b/docs/docs/providers/eval/inline_meta-reference.mdx index b0eb589e0..2c86c18c9 100644 --- a/docs/docs/providers/eval/inline_meta-reference.mdx +++ b/docs/docs/providers/eval/inline_meta-reference.mdx @@ -14,12 +14,12 @@ Meta's reference implementation of evaluation tasks with support for multiple la | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | | +| `kvstore` | `` | No | | | ## Sample Configuration ```yaml kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/meta_reference_eval.db + namespace: eval + backend: kv_default ``` diff --git a/docs/docs/providers/files/inline_localfs.mdx b/docs/docs/providers/files/inline_localfs.mdx index 86d141f93..bff0c4eb9 100644 --- a/docs/docs/providers/files/inline_localfs.mdx +++ b/docs/docs/providers/files/inline_localfs.mdx @@ -15,7 +15,7 @@ Local filesystem-based file storage provider for managing files and documents lo | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `storage_dir` | `` | No | | Directory to store uploaded files | -| `metadata_store` | `utils.sqlstore.sqlstore.SqliteSqlStoreConfig \| utils.sqlstore.sqlstore.PostgresSqlStoreConfig` | No | sqlite | SQL store configuration for file metadata | +| `metadata_store` | `` | No | | SQL store configuration for file metadata | | `ttl_secs` | `` | No | 31536000 | | ## Sample Configuration @@ -23,6 +23,6 @@ Local filesystem-based file storage provider for managing files and documents lo ```yaml storage_dir: ${env.FILES_STORAGE_DIR:=~/.llama/dummy/files} metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/files_metadata.db + table_name: files_metadata + backend: sql_default ``` diff --git a/docs/docs/providers/files/remote_s3.mdx b/docs/docs/providers/files/remote_s3.mdx index 353cedbfb..65cd545c5 100644 --- a/docs/docs/providers/files/remote_s3.mdx +++ b/docs/docs/providers/files/remote_s3.mdx @@ -20,7 +20,7 @@ AWS S3-based file storage provider for scalable cloud file management with metad | `aws_secret_access_key` | `str \| None` | No | | AWS secret access key (optional if using IAM roles) | | `endpoint_url` | `str \| None` | No | | Custom S3 endpoint URL (for MinIO, LocalStack, etc.) | | `auto_create_bucket` | `` | No | False | Automatically create the S3 bucket if it doesn't exist | -| `metadata_store` | `utils.sqlstore.sqlstore.SqliteSqlStoreConfig \| utils.sqlstore.sqlstore.PostgresSqlStoreConfig` | No | sqlite | SQL store configuration for file metadata | +| `metadata_store` | `` | No | | SQL store configuration for file metadata | ## Sample Configuration @@ -32,6 +32,6 @@ aws_secret_access_key: ${env.AWS_SECRET_ACCESS_KEY:=} endpoint_url: ${env.S3_ENDPOINT_URL:=} auto_create_bucket: ${env.S3_AUTO_CREATE_BUCKET:=false} metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/s3_files_metadata.db + table_name: s3_files_metadata + backend: sql_default ``` diff --git a/docs/docs/providers/vector_io/inline_chromadb.mdx b/docs/docs/providers/vector_io/inline_chromadb.mdx index a1858eacc..0be5cd5b3 100644 --- a/docs/docs/providers/vector_io/inline_chromadb.mdx +++ b/docs/docs/providers/vector_io/inline_chromadb.mdx @@ -79,13 +79,13 @@ See [Chroma's documentation](https://docs.trychroma.com/docs/overview/introducti | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `db_path` | `` | No | | | -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | Config for KV store backend | +| `persistence` | `` | No | | Config for KV store backend | ## Sample Configuration ```yaml db_path: ${env.CHROMADB_PATH} -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/chroma_inline_registry.db +persistence: + namespace: vector_io::chroma + backend: kv_default ``` diff --git a/docs/docs/providers/vector_io/inline_faiss.mdx b/docs/docs/providers/vector_io/inline_faiss.mdx index 03bc2a928..3a1fba055 100644 --- a/docs/docs/providers/vector_io/inline_faiss.mdx +++ b/docs/docs/providers/vector_io/inline_faiss.mdx @@ -95,12 +95,12 @@ more details about Faiss in general. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | | +| `persistence` | `` | No | | | ## Sample Configuration ```yaml -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/faiss_store.db +persistence: + namespace: vector_io::faiss + backend: kv_default ``` diff --git a/docs/docs/providers/vector_io/inline_meta-reference.mdx b/docs/docs/providers/vector_io/inline_meta-reference.mdx index bcad86750..17fd40cf5 100644 --- a/docs/docs/providers/vector_io/inline_meta-reference.mdx +++ b/docs/docs/providers/vector_io/inline_meta-reference.mdx @@ -14,14 +14,14 @@ Meta's reference implementation of a vector database. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | | +| `persistence` | `` | No | | | ## Sample Configuration ```yaml -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/faiss_store.db +persistence: + namespace: vector_io::faiss + backend: kv_default ``` ## Deprecation Notice diff --git a/docs/docs/providers/vector_io/inline_milvus.mdx b/docs/docs/providers/vector_io/inline_milvus.mdx index 7e6f15c81..6063edab1 100644 --- a/docs/docs/providers/vector_io/inline_milvus.mdx +++ b/docs/docs/providers/vector_io/inline_milvus.mdx @@ -17,14 +17,14 @@ Please refer to the remote provider documentation. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `db_path` | `` | No | | | -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | Config for KV store backend (SQLite only for now) | +| `persistence` | `` | No | | Config for KV store backend (SQLite only for now) | | `consistency_level` | `` | No | Strong | The consistency level of the Milvus server | ## Sample Configuration ```yaml db_path: ${env.MILVUS_DB_PATH:=~/.llama/dummy}/milvus.db -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/milvus_registry.db +persistence: + namespace: vector_io::milvus + backend: kv_default ``` diff --git a/docs/docs/providers/vector_io/inline_qdrant.mdx b/docs/docs/providers/vector_io/inline_qdrant.mdx index 5c9ab10f2..057d96761 100644 --- a/docs/docs/providers/vector_io/inline_qdrant.mdx +++ b/docs/docs/providers/vector_io/inline_qdrant.mdx @@ -98,13 +98,13 @@ See the [Qdrant documentation](https://qdrant.tech/documentation/) for more deta | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `path` | `` | No | | | -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | | +| `persistence` | `` | No | | | ## Sample Configuration ```yaml path: ${env.QDRANT_PATH:=~/.llama/~/.llama/dummy}/qdrant.db -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/qdrant_registry.db +persistence: + namespace: vector_io::qdrant + backend: kv_default ``` diff --git a/docs/docs/providers/vector_io/inline_sqlite-vec.mdx b/docs/docs/providers/vector_io/inline_sqlite-vec.mdx index aa6992a56..98a372250 100644 --- a/docs/docs/providers/vector_io/inline_sqlite-vec.mdx +++ b/docs/docs/providers/vector_io/inline_sqlite-vec.mdx @@ -408,13 +408,13 @@ See [sqlite-vec's GitHub repo](https://github.com/asg017/sqlite-vec/tree/main) f | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `db_path` | `` | No | | Path to the SQLite database file | -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | Config for KV store backend (SQLite only for now) | +| `persistence` | `` | No | | Config for KV store backend (SQLite only for now) | ## Sample Configuration ```yaml db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/sqlite_vec.db -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/sqlite_vec_registry.db +persistence: + namespace: vector_io::sqlite_vec + backend: kv_default ``` diff --git a/docs/docs/providers/vector_io/inline_sqlite_vec.mdx b/docs/docs/providers/vector_io/inline_sqlite_vec.mdx index 7f69f617d..67cbd0021 100644 --- a/docs/docs/providers/vector_io/inline_sqlite_vec.mdx +++ b/docs/docs/providers/vector_io/inline_sqlite_vec.mdx @@ -17,15 +17,15 @@ Please refer to the sqlite-vec provider documentation. | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `db_path` | `` | No | | Path to the SQLite database file | -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | Config for KV store backend (SQLite only for now) | +| `persistence` | `` | No | | Config for KV store backend (SQLite only for now) | ## Sample Configuration ```yaml db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/sqlite_vec.db -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/sqlite_vec_registry.db +persistence: + namespace: vector_io::sqlite_vec + backend: kv_default ``` ## Deprecation Notice diff --git a/docs/docs/providers/vector_io/remote_chromadb.mdx b/docs/docs/providers/vector_io/remote_chromadb.mdx index 807771003..2aee3eeca 100644 --- a/docs/docs/providers/vector_io/remote_chromadb.mdx +++ b/docs/docs/providers/vector_io/remote_chromadb.mdx @@ -78,13 +78,13 @@ See [Chroma's documentation](https://docs.trychroma.com/docs/overview/introducti | Field | Type | Required | Default | Description | |-------|------|----------|---------|-------------| | `url` | `str \| None` | No | | | -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | Config for KV store backend | +| `persistence` | `` | No | | Config for KV store backend | ## Sample Configuration ```yaml url: ${env.CHROMADB_URL} -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/chroma_remote_registry.db +persistence: + namespace: vector_io::chroma_remote + backend: kv_default ``` diff --git a/docs/docs/providers/vector_io/remote_milvus.mdx b/docs/docs/providers/vector_io/remote_milvus.mdx index 7f7c08122..bf9935d61 100644 --- a/docs/docs/providers/vector_io/remote_milvus.mdx +++ b/docs/docs/providers/vector_io/remote_milvus.mdx @@ -408,7 +408,7 @@ For more details on TLS configuration, refer to the [TLS setup guide](https://mi | `uri` | `` | No | | The URI of the Milvus server | | `token` | `str \| None` | No | | The token of the Milvus server | | `consistency_level` | `` | No | Strong | The consistency level of the Milvus server | -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | Config for KV store backend | +| `persistence` | `` | No | | Config for KV store backend | | `config` | `dict` | No | `{}` | This configuration allows additional fields to be passed through to the underlying Milvus client. See the [Milvus](https://milvus.io/docs/install-overview.md) documentation for more details about Milvus in general. | :::note @@ -420,7 +420,7 @@ This configuration class accepts additional fields beyond those listed above. Yo ```yaml uri: ${env.MILVUS_ENDPOINT} token: ${env.MILVUS_TOKEN} -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/milvus_remote_registry.db +persistence: + namespace: vector_io::milvus_remote + backend: kv_default ``` diff --git a/docs/docs/providers/vector_io/remote_pgvector.mdx b/docs/docs/providers/vector_io/remote_pgvector.mdx index d21810c68..cb70f35d1 100644 --- a/docs/docs/providers/vector_io/remote_pgvector.mdx +++ b/docs/docs/providers/vector_io/remote_pgvector.mdx @@ -218,7 +218,7 @@ See [PGVector's documentation](https://github.com/pgvector/pgvector) for more de | `db` | `str \| None` | No | postgres | | | `user` | `str \| None` | No | postgres | | | `password` | `str \| None` | No | mysecretpassword | | -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig, annotation=NoneType, required=False, default='sqlite', discriminator='type'` | No | | Config for KV store backend (SQLite only for now) | +| `persistence` | `llama_stack.core.storage.datatypes.KVStoreReference \| None` | No | | Config for KV store backend (SQLite only for now) | ## Sample Configuration @@ -228,7 +228,7 @@ port: ${env.PGVECTOR_PORT:=5432} db: ${env.PGVECTOR_DB} user: ${env.PGVECTOR_USER} password: ${env.PGVECTOR_PASSWORD} -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/pgvector_registry.db +persistence: + namespace: vector_io::pgvector + backend: kv_default ``` diff --git a/docs/docs/providers/vector_io/remote_qdrant.mdx b/docs/docs/providers/vector_io/remote_qdrant.mdx index c44a2b937..dff9642b5 100644 --- a/docs/docs/providers/vector_io/remote_qdrant.mdx +++ b/docs/docs/providers/vector_io/remote_qdrant.mdx @@ -26,13 +26,13 @@ Please refer to the inline provider documentation. | `prefix` | `str \| None` | No | | | | `timeout` | `int \| None` | No | | | | `host` | `str \| None` | No | | | -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig` | No | sqlite | | +| `persistence` | `` | No | | | ## Sample Configuration ```yaml api_key: ${env.QDRANT_API_KEY:=} -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/qdrant_registry.db +persistence: + namespace: vector_io::qdrant_remote + backend: kv_default ``` diff --git a/docs/docs/providers/vector_io/remote_weaviate.mdx b/docs/docs/providers/vector_io/remote_weaviate.mdx index 3f1e36422..b809bed2e 100644 --- a/docs/docs/providers/vector_io/remote_weaviate.mdx +++ b/docs/docs/providers/vector_io/remote_weaviate.mdx @@ -75,14 +75,14 @@ See [Weaviate's documentation](https://weaviate.io/developers/weaviate) for more |-------|------|----------|---------|-------------| | `weaviate_api_key` | `str \| None` | No | | The API key for the Weaviate instance | | `weaviate_cluster_url` | `str \| None` | No | localhost:8080 | The URL of the Weaviate cluster | -| `kvstore` | `utils.kvstore.config.RedisKVStoreConfig \| utils.kvstore.config.SqliteKVStoreConfig \| utils.kvstore.config.PostgresKVStoreConfig \| utils.kvstore.config.MongoDBKVStoreConfig, annotation=NoneType, required=False, default='sqlite', discriminator='type'` | No | | Config for KV store backend (SQLite only for now) | +| `persistence` | `llama_stack.core.storage.datatypes.KVStoreReference \| None` | No | | Config for KV store backend (SQLite only for now) | ## Sample Configuration ```yaml weaviate_api_key: null weaviate_cluster_url: ${env.WEAVIATE_CLUSTER_URL:=localhost:8080} -kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/dummy}/weaviate_registry.db +persistence: + namespace: vector_io::weaviate + backend: kv_default ``` diff --git a/docs/docs/references/llama_stack_client_cli_reference.md b/docs/docs/references/llama_stack_client_cli_reference.md index 9bb514a2d..a4321938a 100644 --- a/docs/docs/references/llama_stack_client_cli_reference.md +++ b/docs/docs/references/llama_stack_client_cli_reference.md @@ -32,7 +32,6 @@ Commands: scoring_functions Manage scoring functions. shields Manage safety shield services. toolgroups Manage available tool groups. - vector_dbs Manage vector databases. ``` ### `llama-stack-client configure` @@ -211,53 +210,6 @@ Unregister a model from distribution endpoint llama-stack-client models unregister ``` -## Vector DB Management -Manage vector databases. - - -### `llama-stack-client vector_dbs list` -Show available vector dbs on distribution endpoint -```bash -llama-stack-client vector_dbs list -``` -``` -┏━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓ -┃ identifier ┃ provider_id ┃ provider_resource_id ┃ vector_db_type ┃ params ┃ -┡━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩ -│ my_demo_vector_db │ faiss │ my_demo_vector_db │ │ embedding_dimension: 768 │ -│ │ │ │ │ embedding_model: nomic-embed-text-v1.5 │ -│ │ │ │ │ type: vector_db │ -│ │ │ │ │ │ -└──────────────────────────┴─────────────┴──────────────────────────┴────────────────┴───────────────────────────────────┘ -``` - -### `llama-stack-client vector_dbs register` -Create a new vector db -```bash -llama-stack-client vector_dbs register [--provider-id ] [--provider-vector-db-id ] [--embedding-model ] [--embedding-dimension ] -``` - - -Required arguments: -- `VECTOR_DB_ID`: Vector DB ID - -Optional arguments: -- `--provider-id`: Provider ID for the vector db -- `--provider-vector-db-id`: Provider's vector db ID -- `--embedding-model`: Embedding model to use. Default: `nomic-embed-text-v1.5` -- `--embedding-dimension`: Dimension of embeddings. Default: 768 - -### `llama-stack-client vector_dbs unregister` -Delete a vector db -```bash -llama-stack-client vector_dbs unregister -``` - - -Required arguments: -- `VECTOR_DB_ID`: Vector DB ID - - ## Shield Management Manage safety shield services. ### `llama-stack-client shields list` diff --git a/docs/getting_started.ipynb b/docs/getting_started.ipynb index e1e2ff82e..a03de73f5 100644 --- a/docs/getting_started.ipynb +++ b/docs/getting_started.ipynb @@ -57,6 +57,62 @@ "\n" ] }, + { + "cell_type": "markdown", + "id": "be3b12f8-b857-4f02-b451-a5a6b5be0814", + "metadata": {}, + "source": [ + "### 1.2 Install llama-stack and llama-stack-client packages" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "2dde9482-0e5d-49ca-a350-1e239eb341c5", + "metadata": { + "collapsed": true, + "jupyter": { + "outputs_hidden": true + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: uv in /opt/homebrew/Caskroom/miniconda/base/envs/test/lib/python3.12/site-packages (0.9.4)\n", + "\u001b[2mUsing Python 3.12.12 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/test\u001b[0m\n", + "\u001b[2K\u001b[2mResolved \u001b[1m84 packages\u001b[0m \u001b[2min 603ms\u001b[0m\u001b[0m \u001b[0m\n", + "\u001b[2K\u001b[2mPrepared \u001b[1m1 package\u001b[0m \u001b[2min 371ms\u001b[0m\u001b[0m \n", + "\u001b[2K\u001b[2mInstalled \u001b[1m3 packages\u001b[0m \u001b[2min 50ms\u001b[0m\u001b[0m \u001b[0m\n", + " \u001b[32m+\u001b[39m \u001b[1mecdsa\u001b[0m\u001b[2m==0.19.1\u001b[0m\n", + " \u001b[32m+\u001b[39m \u001b[1mllama-stack\u001b[0m\u001b[2m==0.2.23\u001b[0m\n", + " \u001b[32m+\u001b[39m \u001b[1mpython-jose\u001b[0m\u001b[2m==3.5.0\u001b[0m\n", + "\u001b[2mUsing Python 3.12.12 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/test\u001b[0m\n", + "\u001b[2K\u001b[2mResolved \u001b[1m35 packages\u001b[0m \u001b[2min 40ms\u001b[0m\u001b[0m \u001b[0m\n", + "\u001b[2K\u001b[2mPrepared \u001b[1m1 package\u001b[0m \u001b[2min 1.19s\u001b[0m\u001b[0m \n", + "\u001b[2mUninstalled \u001b[1m1 package\u001b[0m \u001b[2min 3ms\u001b[0m\u001b[0m\n", + "\u001b[2K\u001b[2mInstalled \u001b[1m1 package\u001b[0m \u001b[2min 9ms\u001b[0m\u001b[0m=0.3.0a6 (from file:///Users/erich\u001b[0m\n", + " \u001b[33m~\u001b[39m \u001b[1mllama-stack-client\u001b[0m\u001b[2m==0.3.0a6 (from file:///Users/erichuang/projects/llama-stack-client-python)\u001b[0m\n", + "\u001b[2mUsing Python 3.12.12 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/test\u001b[0m\n", + "\u001b[2mAudited \u001b[1m52 packages\u001b[0m \u001b[2min 1.18s\u001b[0m\u001b[0m\n", + "\u001b[2mUsing Python 3.12.12 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/test\u001b[0m\n", + "\u001b[2mAudited \u001b[1m1 package\u001b[0m \u001b[2min 67ms\u001b[0m\u001b[0m\n", + "\u001b[2mUsing Python 3.12.12 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/test\u001b[0m\n", + "\u001b[2mAudited \u001b[1m3 packages\u001b[0m \u001b[2min 43ms\u001b[0m\u001b[0m\n", + "\u001b[2mUsing Python 3.12.12 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/test\u001b[0m\n", + "\u001b[2mAudited \u001b[1m3 packages\u001b[0m \u001b[2min 125ms\u001b[0m\u001b[0m\n" + ] + } + ], + "source": [ + "!pip install uv\n", + "!uv pip install llama-stack llama-stack-client\n", + "\n", + "# Installs dependencies for the starter distribution\n", + "!uv run --with llama-stack llama stack list-deps starter | xargs -L1 uv pip install" + ] + }, { "cell_type": "markdown", "id": "oDUB7M_qe-Gs", @@ -64,7 +120,7 @@ "id": "oDUB7M_qe-Gs" }, "source": [ - "### 1.2. Setup and Running a Llama Stack server\n", + "### 1.3. Setup and Running a Llama Stack server\n", "\n", "Llama Stack is architected as a collection of APIs that provide developers with the building blocks to build AI applications. \n", "\n", @@ -75,61 +131,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "J2kGed0R5PSf", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, - "collapsed": true, "id": "J2kGed0R5PSf", "outputId": "2478ea60-8d35-48a1-b011-f233831740c5" }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: uv in /opt/homebrew/Caskroom/miniconda/base/envs/stack/lib/python3.10/site-packages (0.5.29)\n", - "Environment '/Users/hjshah/git/llama-stack/.venv' already exists, re-using it.\n", - "Virtual environment /Users/hjshah/git/llama-stack/.venv is already active\n", - "\u001b[2mUsing Python 3.10.16 environment at: /Users/hjshah/git/llama-stack/.venv\u001b[0m\n", - "\u001b[2mAudited \u001b[1m1 package\u001b[0m \u001b[2min 314ms\u001b[0m\u001b[0m\n", - "Installing pip dependencies\n", - "\u001b[2mUsing Python 3.10.16 environment at: /Users/hjshah/git/llama-stack/.venv\u001b[0m\n", - "\u001b[2K\u001b[2mResolved \u001b[1m125 packages\u001b[0m \u001b[2min 646ms\u001b[0m\u001b[0m \u001b[0m\n", - "\u001b[2mUninstalled \u001b[1m1 package\u001b[0m \u001b[2min 404ms\u001b[0m\u001b[0m\n", - "\u001b[2K\u001b[2mInstalled \u001b[1m1 package\u001b[0m \u001b[2min 129ms\u001b[0m\u001b[0m \u001b[0m\n", - " \u001b[31m-\u001b[39m \u001b[1mnumpy\u001b[0m\u001b[2m==2.2.3\u001b[0m\n", - " \u001b[32m+\u001b[39m \u001b[1mnumpy\u001b[0m\u001b[2m==1.26.4\u001b[0m\n", - "sentence-transformers --no-deps\n", - "\u001b[2mUsing Python 3.10.16 environment at: /Users/hjshah/git/llama-stack/.venv\u001b[0m\n", - "\u001b[2mAudited \u001b[1m1 package\u001b[0m \u001b[2min 54ms\u001b[0m\u001b[0m\n", - "torch torchvision --index-url https://download.pytorch.org/whl/cpu\n", - "\u001b[2mUsing Python 3.10.16 environment at: /Users/hjshah/git/llama-stack/.venv\u001b[0m\n", - "\u001b[2mAudited \u001b[1m2 packages\u001b[0m \u001b[2min 10ms\u001b[0m\u001b[0m\n", - "\u001b[32mBuild Successful!\u001b[0m\n" - ] - } - ], + "outputs": [], "source": [ "import os\n", "import subprocess\n", "import time\n", "\n", - "!pip install uv\n", "\n", "if \"UV_SYSTEM_PYTHON\" in os.environ:\n", " del os.environ[\"UV_SYSTEM_PYTHON\"]\n", "\n", - "# this command installs all the dependencies needed for the llama stack server with the together inference provider\n", - "!uv run --with llama-stack llama stack list-deps together | xargs -L1 uv pip install\n", - "!uv run --with llama-stack llama stack run together\n", "\n", "def run_llama_stack_server_background():\n", " log_file = open(\"llama_stack_server.log\", \"w\")\n", " process = subprocess.Popen(\n", - " \"uv run --with llama-stack llama stack run together\",\n", + " \"uv run --with llama-stack llama stack run starter\",\n", " shell=True,\n", " stdout=log_file,\n", " stderr=log_file,\n", @@ -152,6 +177,7 @@ " for _ in range(max_retries):\n", " try:\n", " response = requests.get(url)\n", + " print(response)\n", " if response.status_code == 200:\n", " print(\"\\nServer is ready!\")\n", " return True\n", @@ -179,7 +205,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "id": "f779283d", "metadata": {}, "outputs": [ @@ -187,8 +213,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting Llama Stack server with PID: 79142\n", - "Waiting for server to start..........................\n", + "Starting Llama Stack server with PID: 86923\n", + "Waiting for server to start..........\n", + "\n", "Server is ready!\n" ] } @@ -203,9 +230,9 @@ "id": "90eb721b", "metadata": {}, "source": [ - "### 1.4. Install and Configure the Client\n", + "### 1.4. Configure the Client\n", "\n", - "Now that we have our Llama Stack server running locally, we need to install the client package to interact with it. The `llama-stack-client` provides a simple Python interface to access all the functionality of Llama Stack, including:\n", + "Now that we have our Llama Stack server running locally, we will setup the client to interact with it. The `llama-stack-client` provides a simple Python interface to access all the functionality of Llama Stack, including:\n", "\n", "- Chat Completions ( text and multimodal )\n", "- Safety Shields \n", @@ -216,34 +243,13 @@ "\n", "In the next cells, we'll:\n", "\n", - "1. Install the client package\n", - "2. Set up API keys for external services (Together AI and Tavily Search)\n", - "3. Initialize the client to connect to our local server\n" + "1. Set up API keys for external services (Together AI and Tavily Search)\n", + "2. Initialize the client to connect to our local server\n" ] }, { "cell_type": "code", - "execution_count": 3, - "id": "2e68e32a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[2mUsing Python 3.10.16 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/stack\u001b[0m\n", - "\u001b[2K\u001b[2mResolved \u001b[1m31 packages\u001b[0m \u001b[2min 284ms\u001b[0m\u001b[0m \u001b[0m\n", - "\u001b[2mAudited \u001b[1m31 packages\u001b[0m \u001b[2min 0.04ms\u001b[0m\u001b[0m\n" - ] - } - ], - "source": [ - "!pip install -U llama-stack-client" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 4, "id": "E1UFuJC570Tk", "metadata": { "colab": { @@ -373,7 +379,6 @@ "52fe404ec9c14db2a7279b4c154eef3d" ] }, - "collapsed": true, "id": "E1UFuJC570Tk", "outputId": "aebb69d4-c167-4de5-eb8a-dd19dd538f63" }, @@ -451,46 +456,268 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 9, "id": "ruO9jQna_t_S", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, - "collapsed": true, "id": "ruO9jQna_t_S", "outputId": "ab1722a7-62ab-43bb-9cab-4e45bf62068a" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: GET http://0.0.0.0:8321/v1/models \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: GET http://0.0.0.0:8321/v1/shields \"HTTP/1.1 200 OK\"\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ "Available models:\n", - "- all-MiniLM-L6-v2\n", - "- meta-llama/Llama-3.1-405B-Instruct-FP8\n", - "- meta-llama/Llama-3.1-70B-Instruct\n", - "- meta-llama/Llama-3.1-8B-Instruct\n", - "- meta-llama/Llama-3.2-11B-Vision-Instruct\n", - "- meta-llama/Llama-3.2-11B-Vision-Instruct-Turbo\n", - "- meta-llama/Llama-3.2-3B-Instruct\n", - "- meta-llama/Llama-3.2-3B-Instruct-Turbo\n", - "- meta-llama/Llama-3.2-90B-Vision-Instruct\n", - "- meta-llama/Llama-3.2-90B-Vision-Instruct-Turbo\n", - "- meta-llama/Llama-3.3-70B-Instruct\n", - "- meta-llama/Llama-3.3-70B-Instruct-Turbo\n", - "- meta-llama/Llama-Guard-3-11B-Vision\n", - "- meta-llama/Llama-Guard-3-11B-Vision-Turbo\n", - "- meta-llama/Llama-Guard-3-8B\n", - "- meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo\n", - "- meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo\n", - "- meta-llama/Meta-Llama-3.1-8B-Instruct-Turbo\n", - "- meta-llama/Meta-Llama-Guard-3-8B\n", - "- togethercomputer/m2-bert-80M-32k-retrieval\n", - "- togethercomputer/m2-bert-80M-8k-retrieval\n", + "- fireworks/accounts/fireworks/models/flux-1-dev-fp8\n", + "- fireworks/accounts/fireworks/models/flux-kontext-max\n", + "- fireworks/accounts/fireworks/models/flux-kontext-pro\n", + "- fireworks/accounts/sentientfoundation-serverless/models/dobby-mini-unhinged-plus-llama-3-1-8b\n", + "- fireworks/accounts/sentientfoundation/models/dobby-unhinged-llama-3-3-70b-new\n", + "- fireworks/accounts/fireworks/models/gpt-oss-120b\n", + "- fireworks/accounts/fireworks/models/qwen3-235b-a22b-instruct-2507\n", + "- fireworks/accounts/fireworks/models/qwen3-235b-a22b-thinking-2507\n", + "- fireworks/accounts/fireworks/models/deepseek-v3-0324\n", + "- fireworks/accounts/fireworks/models/kimi-k2-instruct\n", + "- fireworks/accounts/fireworks/models/llama-v3p3-70b-instruct\n", + "- fireworks/accounts/fireworks/models/qwen3-235b-a22b\n", + "- fireworks/accounts/fireworks/models/deepseek-v3p1\n", + "- fireworks/accounts/fireworks/models/flux-1-schnell-fp8\n", + "- fireworks/accounts/fireworks/models/llama4-scout-instruct-basic\n", + "- fireworks/accounts/fireworks/models/llama-v3p1-70b-instruct\n", + "- fireworks/accounts/fireworks/models/deepseek-r1-0528\n", + "- fireworks/accounts/fireworks/models/llama4-maverick-instruct-basic\n", + "- fireworks/accounts/fireworks/models/qwen2p5-vl-32b-instruct\n", + "- fireworks/accounts/fireworks/models/deepseek-v3p1-terminus\n", + "- fireworks/accounts/fireworks/models/llama-v3p1-8b-instruct\n", + "- fireworks/accounts/fireworks/models/qwen3-coder-480b-a35b-instruct\n", + "- fireworks/accounts/fireworks/models/qwen3-30b-a3b-instruct-2507\n", + "- fireworks/accounts/fireworks/models/qwen3-30b-a3b-thinking-2507\n", + "- fireworks/accounts/fireworks/models/qwen3-embedding-8b\n", + "- fireworks/accounts/fireworks/models/glm-4p5\n", + "- fireworks/accounts/fireworks/models/qwen3-reranker-8b\n", + "- fireworks/accounts/fireworks/models/kimi-k2-instruct-0905\n", + "- fireworks/accounts/fireworks/models/deepseek-r1\n", + "- fireworks/accounts/fireworks/models/deepseek-v3\n", + "- fireworks/accounts/fireworks/models/deepseek-r1-basic\n", + "- fireworks/accounts/fireworks/models/glm-4p6\n", + "- fireworks/accounts/tvergho-87e44d/models/debatecards-70b-ft-3epoch-dpo-v2\n", + "- fireworks/accounts/fireworks/models/gpt-oss-20b\n", + "- fireworks/accounts/fireworks/models/qwen3-30b-a3b\n", + "- fireworks/accounts/fireworks/models/glm-4p5-air\n", + "- fireworks/accounts/fireworks/models/mixtral-8x22b-instruct\n", + "- fireworks/accounts/fireworks/models/llama-v3p1-405b-instruct\n", + "- fireworks/accounts/fireworks/models/qwen3-coder-30b-a3b-instruct\n", + "- together/Alibaba-NLP/gte-modernbert-base\n", + "- together/arcee-ai/AFM-4.5B\n", + "- together/arcee-ai/coder-large\n", + "- together/arcee-ai/maestro-reasoning\n", + "- together/arcee-ai/virtuoso-large\n", + "- together/arcee_ai/arcee-spotlight\n", + "- together/arize-ai/qwen-2-1.5b-instruct\n", + "- together/BAAI/bge-base-en-v1.5\n", + "- together/BAAI/bge-large-en-v1.5\n", + "- together/black-forest-labs/FLUX.1-dev\n", + "- together/black-forest-labs/FLUX.1-dev-lora\n", + "- together/black-forest-labs/FLUX.1-kontext-dev\n", + "- together/black-forest-labs/FLUX.1-kontext-max\n", + "- together/black-forest-labs/FLUX.1-kontext-pro\n", + "- together/black-forest-labs/FLUX.1-krea-dev\n", + "- together/black-forest-labs/FLUX.1-pro\n", + "- together/black-forest-labs/FLUX.1-schnell\n", + "- together/black-forest-labs/FLUX.1-schnell-Free\n", + "- together/black-forest-labs/FLUX.1.1-pro\n", + "- together/cartesia/sonic\n", + "- together/cartesia/sonic-2\n", + "- together/codellama/CodeLlama-34b-Instruct-hf\n", + "- together/deepcogito/cogito-v2-preview-deepseek-671b\n", + "- together/deepcogito/cogito-v2-preview-llama-109B-MoE\n", + "- together/deepcogito/cogito-v2-preview-llama-405B\n", + "- together/deepcogito/cogito-v2-preview-llama-70B\n", + "- together/deepseek-ai/DeepSeek-R1\n", + "- together/deepseek-ai/DeepSeek-R1-0528-tput\n", + "- together/deepseek-ai/DeepSeek-R1-Distill-Llama-70B\n", + "- together/deepseek-ai/DeepSeek-R1-Distill-Llama-70B-free\n", + "- together/deepseek-ai/DeepSeek-R1-Distill-Qwen-14B\n", + "- together/deepseek-ai/DeepSeek-V3\n", + "- together/deepseek-ai/DeepSeek-V3.1\n", + "- together/google/gemma-3n-E4B-it\n", + "- together/intfloat/multilingual-e5-large-instruct\n", + "- together/marin-community/marin-8b-instruct\n", + "- together/meta-llama/Llama-3-70b-chat-hf\n", + "- together/meta-llama/Llama-3-70b-hf\n", + "- together/meta-llama/Llama-3.1-405B-Instruct\n", + "- together/meta-llama/Llama-3.2-1B-Instruct\n", + "- together/meta-llama/Llama-3.2-3B-Instruct-Turbo\n", + "- together/meta-llama/Llama-3.3-70B-Instruct-Turbo\n", + "- together/meta-llama/Llama-3.3-70B-Instruct-Turbo-Free\n", + "- together/meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8\n", + "- together/meta-llama/Llama-4-Scout-17B-16E-Instruct\n", + "- together/meta-llama/Llama-Guard-3-11B-Vision-Turbo\n", + "- together/meta-llama/Llama-Guard-4-12B\n", + "- together/Meta-Llama/Llama-Guard-7b\n", + "- together/meta-llama/LlamaGuard-2-8b\n", + "- together/meta-llama/Meta-Llama-3-70B-Instruct-Turbo\n", + "- together/meta-llama/Meta-Llama-3-8B-Instruct\n", + "- together/meta-llama/Meta-Llama-3-8B-Instruct-Lite\n", + "- together/meta-llama/Meta-Llama-3.1-405B-Instruct-Lite-Pro\n", + "- together/meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo\n", + "- together/meta-llama/Meta-Llama-3.1-70B-Instruct-Reference\n", + "- together/meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo\n", + "- together/meta-llama/Meta-Llama-3.1-8B-Instruct-Reference\n", + "- together/meta-llama/Meta-Llama-Guard-3-8B\n", + "- together/mistralai/Mistral-7B-Instruct-v0.1\n", + "- together/mistralai/Mistral-7B-Instruct-v0.2\n", + "- together/mistralai/Mistral-7B-Instruct-v0.3\n", + "- together/mistralai/Mistral-Small-24B-Instruct-2501\n", + "- together/mistralai/Mixtral-8x7B-Instruct-v0.1\n", + "- together/mixedbread-ai/Mxbai-Rerank-Large-V2\n", + "- together/moonshotai/Kimi-K2-Instruct\n", + "- together/moonshotai/Kimi-K2-Instruct-0905\n", + "- together/nvidia/NVIDIA-Nemotron-Nano-9B-v2\n", + "- together/openai/gpt-oss-120b\n", + "- together/openai/gpt-oss-20b\n", + "- together/openai/whisper-large-v3\n", + "- together/Qwen/Qwen2.5-14B-Instruct\n", + "- together/Qwen/Qwen2.5-72B-Instruct\n", + "- together/Qwen/Qwen2.5-72B-Instruct-Turbo\n", + "- together/Qwen/Qwen2.5-7B-Instruct-Turbo\n", + "- together/Qwen/Qwen2.5-Coder-32B-Instruct\n", + "- together/Qwen/Qwen2.5-VL-72B-Instruct\n", + "- together/Qwen/Qwen3-235B-A22B-fp8-tput\n", + "- together/Qwen/Qwen3-235B-A22B-Instruct-2507-tput\n", + "- together/Qwen/Qwen3-235B-A22B-Thinking-2507\n", + "- together/Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8\n", + "- together/Qwen/Qwen3-Next-80B-A3B-Instruct\n", + "- together/Qwen/Qwen3-Next-80B-A3B-Thinking\n", + "- together/Qwen/QwQ-32B\n", + "- together/Salesforce/Llama-Rank-V1\n", + "- together/scb10x/scb10x-typhoon-2-1-gemma3-12b\n", + "- together/ServiceNow-AI/Apriel-1.5-15b-Thinker\n", + "- together/togethercomputer/m2-bert-80M-32k-retrieval\n", + "- together/togethercomputer/MoA-1\n", + "- together/togethercomputer/MoA-1-Turbo\n", + "- together/togethercomputer/Refuel-Llm-V2\n", + "- together/togethercomputer/Refuel-Llm-V2-Small\n", + "- together/Virtue-AI/VirtueGuard-Text-Lite\n", + "- together/zai-org/GLM-4.5-Air-FP8\n", + "- bedrock/meta.llama3-1-8b-instruct-v1:0\n", + "- bedrock/meta.llama3-1-70b-instruct-v1:0\n", + "- bedrock/meta.llama3-1-405b-instruct-v1:0\n", + "- openai/gpt-4-0613\n", + "- openai/gpt-4\n", + "- openai/gpt-3.5-turbo\n", + "- openai/gpt-5-search-api-2025-10-14\n", + "- openai/gpt-realtime-mini\n", + "- openai/gpt-realtime-mini-2025-10-06\n", + "- openai/sora-2\n", + "- openai/sora-2-pro\n", + "- openai/davinci-002\n", + "- openai/babbage-002\n", + "- openai/gpt-3.5-turbo-instruct\n", + "- openai/gpt-3.5-turbo-instruct-0914\n", + "- openai/dall-e-3\n", + "- openai/dall-e-2\n", + "- openai/gpt-4-1106-preview\n", + "- openai/gpt-3.5-turbo-1106\n", + "- openai/tts-1-hd\n", + "- openai/tts-1-1106\n", + "- openai/tts-1-hd-1106\n", + "- openai/text-embedding-3-small\n", + "- openai/text-embedding-3-large\n", + "- openai/gpt-4-0125-preview\n", + "- openai/gpt-4-turbo-preview\n", + "- openai/gpt-3.5-turbo-0125\n", + "- openai/gpt-4-turbo\n", + "- openai/gpt-4-turbo-2024-04-09\n", + "- openai/gpt-4o\n", + "- openai/gpt-4o-2024-05-13\n", + "- openai/gpt-4o-mini-2024-07-18\n", + "- openai/gpt-4o-mini\n", + "- openai/gpt-4o-2024-08-06\n", + "- openai/chatgpt-4o-latest\n", + "- openai/o1-mini-2024-09-12\n", + "- openai/o1-mini\n", + "- openai/gpt-4o-realtime-preview-2024-10-01\n", + "- openai/gpt-4o-audio-preview-2024-10-01\n", + "- openai/gpt-4o-audio-preview\n", + "- openai/gpt-4o-realtime-preview\n", + "- openai/omni-moderation-latest\n", + "- openai/omni-moderation-2024-09-26\n", + "- openai/gpt-4o-realtime-preview-2024-12-17\n", + "- openai/gpt-4o-audio-preview-2024-12-17\n", + "- openai/gpt-4o-mini-realtime-preview-2024-12-17\n", + "- openai/gpt-4o-mini-audio-preview-2024-12-17\n", + "- openai/o1-2024-12-17\n", + "- openai/o1\n", + "- openai/gpt-4o-mini-realtime-preview\n", + "- openai/gpt-4o-mini-audio-preview\n", + "- openai/o3-mini\n", + "- openai/o3-mini-2025-01-31\n", + "- openai/gpt-4o-2024-11-20\n", + "- openai/gpt-4o-search-preview-2025-03-11\n", + "- openai/gpt-4o-search-preview\n", + "- openai/gpt-4o-mini-search-preview-2025-03-11\n", + "- openai/gpt-4o-mini-search-preview\n", + "- openai/gpt-4o-transcribe\n", + "- openai/gpt-4o-mini-transcribe\n", + "- openai/o1-pro-2025-03-19\n", + "- openai/o1-pro\n", + "- openai/gpt-4o-mini-tts\n", + "- openai/o3-2025-04-16\n", + "- openai/o4-mini-2025-04-16\n", + "- openai/o3\n", + "- openai/o4-mini\n", + "- openai/gpt-4.1-2025-04-14\n", + "- openai/gpt-4.1\n", + "- openai/gpt-4.1-mini-2025-04-14\n", + "- openai/gpt-4.1-mini\n", + "- openai/gpt-4.1-nano-2025-04-14\n", + "- openai/gpt-4.1-nano\n", + "- openai/gpt-image-1\n", + "- openai/codex-mini-latest\n", + "- openai/gpt-4o-realtime-preview-2025-06-03\n", + "- openai/gpt-4o-audio-preview-2025-06-03\n", + "- openai/o4-mini-deep-research\n", + "- openai/gpt-4o-transcribe-diarize\n", + "- openai/o4-mini-deep-research-2025-06-26\n", + "- openai/gpt-5-chat-latest\n", + "- openai/gpt-5-2025-08-07\n", + "- openai/gpt-5\n", + "- openai/gpt-5-mini-2025-08-07\n", + "- openai/gpt-5-mini\n", + "- openai/gpt-5-nano-2025-08-07\n", + "- openai/gpt-5-nano\n", + "- openai/gpt-audio-2025-08-28\n", + "- openai/gpt-realtime\n", + "- openai/gpt-realtime-2025-08-28\n", + "- openai/gpt-audio\n", + "- openai/gpt-5-codex\n", + "- openai/gpt-image-1-mini\n", + "- openai/gpt-5-pro-2025-10-06\n", + "- openai/gpt-5-pro\n", + "- openai/gpt-audio-mini\n", + "- openai/gpt-audio-mini-2025-10-06\n", + "- openai/gpt-5-search-api\n", + "- openai/gpt-3.5-turbo-16k\n", + "- openai/tts-1\n", + "- openai/whisper-1\n", + "- openai/text-embedding-ada-002\n", + "- sentence-transformers/nomic-ai/nomic-embed-text-v1.5\n", + "- sentence-transformers/all-MiniLM-L6-v2\n", "----\n", "Available shields (safety models):\n", - "meta-llama/Llama-Guard-3-8B\n", + "together/meta-llama/Llama-Guard-4-12B\n", "----\n" ] } @@ -505,7 +732,7 @@ "print(\"----\")\n", "print(\"Available shields (safety models):\")\n", "for s in client.shields.list():\n", - " print(s.identifier)\n", + " print(s.provider_resource_id)\n", "print(\"----\")\n" ] }, @@ -523,7 +750,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 41, "id": "77c29dba", "metadata": { "colab": { @@ -533,16 +760,27 @@ "outputId": "4857974f-4c70-4bc4-f90a-6ae49dc9c41e" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/chat/completions \"HTTP/1.1 200 OK\"\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "With gentle eyes and a soft, fuzzy face, the llama roams the Andes with a peaceful, gentle pace. Its long neck bends as it grazes with glee, a symbol of serenity in a world wild and free.\n" + "Here is a two-sentence poem about a llama:\n", + "\n", + "With soft fur and gentle eyes, the llama roams with gentle surprise, a majestic creature of the Andes high. Its soft humming fills the Andean air, a soothing sound beyond compare.\n" ] } ], "source": [ - "model_id = \"meta-llama/Llama-3.3-70B-Instruct\"\n", + "model_id = \"together/meta-llama/Llama-4-Maverick-17B-128E-Instruct-FP8\"\n", + "# TODO remove\n", + "# model_id = \"openai/gpt-4o\"\n", "\n", "response = client.chat.completions.create(\n", " model=model_id,\n", @@ -569,40 +807,64 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 12, "id": "3fdf9df6", "metadata": { "id": "3fdf9df6" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/chat/completions \"HTTP/1.1 200 OK\"\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "\u001b[36m> Response: The most famous Prime Minister of England during World War II was undoubtedly Winston Churchill. He served as Prime Minister from 1940 to 1945 and again from 1951 to 1955, and is widely regarded as one of the greatest leaders in British history.\n", + "\u001b[36m> Response: The most famous Prime Minister of England during World War II was Winston Churchill. He served as Prime Minister from 1940 to 1945 and again from 1951 to 1955. Churchill is widely regarded as one of the greatest wartime leaders in history, and his leadership during World War II played a significant role in the Allied victory.\n", "\n", - "Churchill played a crucial role in rallying the British people during the war, and his oratory skills and leadership helped to boost morale and resistance against the Nazi threat. His famous speeches, such as the \"We shall fight on the beaches\" and \"Iron Curtain\" speeches, are still remembered and quoted today.\n", + "Churchill was known for his oratory skills, and his speeches during the war, such as \"We shall fight on the beaches\" and \"Their finest hour\", helped to rally the British people during a time of great crisis. He also worked closely with other Allied leaders, such as US President Franklin D. Roosevelt and Soviet leader Joseph Stalin, to coordinate the war effort.\n", "\n", - "Churchill's leadership during World War II was marked by his unwavering determination to defeat Nazi Germany, and he worked closely with other Allied leaders, including US President Franklin D. Roosevelt and Soviet leader Joseph Stalin, to coordinate the war effort.\n", + "Churchill's leadership and vision helped to galvanize the British people during the war, and his legacy as a wartime leader has endured. He is often credited with helping to lead Britain to victory against Nazi Germany and its allies, and his name has become synonymous with British resilience and determination during World War II.\u001b[0m\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/chat/completions \"HTTP/1.1 200 OK\"\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[36m> Response: One of Winston Churchill's most famous quotes is:\n", "\n", - "Churchill's legacy extends far beyond his wartime leadership, and he is remembered for his many contributions to British politics, literature, and culture. He was a prolific writer and painter, and was awarded the Nobel Prize in Literature in 1953.\n", + "**\"We shall fight on the beaches\"**\n", "\n", - "Overall, Winston Churchill is widely regarded as one of the most famous and influential Prime Ministers in British history, and his leadership during World War II remains an iconic and enduring symbol of British resilience and determination.\u001b[0m\n", - "\u001b[36m> Response: Winston Churchill had many famous quotes, but one of his most iconic and enduring quotes is:\n", + "However, his most famous quote is often considered to be:\n", "\n", - "\"We shall fight on the beaches, we shall fight on the landing grounds, we shall fight in the fields and in the streets, we shall fight in the hills; we shall never surrender.\"\n", + "**\"Blood, toil, tears and sweat: We have before us an ordeal of the most grievous kind.\"**\n", "\n", - "This quote is from his speech to the House of Commons on June 4, 1940, during the early stages of World War II, when Nazi Germany was threatening to invade Britain. The speech is known as the \"We Shall Fight on the Beaches\" speech, and it is considered one of the most famous and inspiring speeches in history.\n", + "But arguably his most iconic and widely recognized quote is:\n", "\n", - "In this speech, Churchill rallied the British people to stand strong against the Nazi threat, and his words helped to boost morale and resistance. The quote has since become a symbol of British determination and resilience, and is often referenced and parodied in popular culture.\n", + "**\"We shall fight on the beaches, in the streets, in the fields and in the hills. We shall never surrender.\"**\n", "\n", - "Other notable quotes from Churchill include:\n", + "This quote was from his first speech as Prime Minister, delivered to the House of Commons on June 4, 1940, during the early stages of World War II, when Nazi Germany was threatening to invade Britain. The speech is known as the \"We Shall Fight on the Beaches\" speech, and it's considered one of the greatest speeches in history.\n", "\n", - "* \"Blood, toil, tears, and sweat\" (from his first speech as Prime Minister in 1940)\n", - "* \"An iron curtain has descended across the continent\" (from his speech in 1946, referring to the Soviet Union's dominance in Eastern Europe)\n", - "* \"Never was so much owed by so many to so few\" (from his speech in 1940, referring to the bravery of the Royal Air Force during the Battle of Britain)\n", + "However, if I had to pick one that is most widely recognized and often cited as his most famous quote, it would be:\n", "\n", - "But \"We shall fight on the beaches\" remains his most famous and enduring quote.\u001b[0m\n" + "**\"Iron Curtain\"**\n", + "\n", + " Although not exactly a quote from WW2. It was \"From Stettin in the Baltic to Trieste in the Adriatic, an iron curtain has descended across the continent.\" \n", + "\n", + "This phrase was used in a speech in Fulton, Missouri, on March 5, 1946. It was a speech that alerted the West to the danger of Soviet expansionism and marked the beginning of the Cold War.\n", + "\n", + "Each of these quotes captures a moment in history and convey's a powerful message that has endured for generations.\u001b[0m\n" ] } ], @@ -656,7 +918,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 13, "id": "9496f75c", "metadata": { "colab": { @@ -666,13 +928,38 @@ "outputId": "7d93a4cf-a5d4-4741-b6eb-6bce3a27ff66" }, "outputs": [ + { + "name": "stdin", + "output_type": "stream", + "text": [ + "User> hello\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/chat/completions \"HTTP/1.1 200 OK\"\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[36m> Response: Hello! It's nice to meet you. Is there something I can help you with or would you like to chat?\u001b[0m\n" + ] + }, + { + "name": "stdin", + "output_type": "stream", + "text": [ + "User> exit\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "\u001b[36m> Response: Fuzzy code abides\n", - "Llama's gentle syntax\n", - "Wisdom in the stack\u001b[0m\n", "\u001b[33mEnding conversation. Goodbye!\u001b[0m\n" ] } @@ -723,7 +1010,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 57, "id": "d119026e", "metadata": { "colab": { @@ -733,34 +1020,40 @@ "outputId": "ebd6dc2b-8542-4370-b08a-e3a7dede6d17" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/chat/completions \"HTTP/1.1 200 OK\"\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ "User> Write me a sonnet about llama\n", - "\u001b[36mAssistant> \u001b[0m\u001b[33mIn\u001b[0m\u001b[33m And\u001b[0m\u001b[33mean\u001b[0m\u001b[33m high\u001b[0m\u001b[33mlands\u001b[0m\u001b[33m,\u001b[0m\u001b[33m where\u001b[0m\u001b[33m the\u001b[0m\u001b[33m air\u001b[0m\u001b[33m is\u001b[0m\u001b[33m thin\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mA\u001b[0m\u001b[33m creature\u001b[0m\u001b[33m ro\u001b[0m\u001b[33mams\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m gentle\u001b[0m\u001b[33m,\u001b[0m\u001b[33m curious\u001b[0m\u001b[33m eyes\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mThe\u001b[0m\u001b[33m llama\u001b[0m\u001b[33m,\u001b[0m\u001b[33m soft\u001b[0m\u001b[33m and\u001b[0m\u001b[33m silent\u001b[0m\u001b[33m,\u001b[0m\u001b[33m steps\u001b[0m\u001b[33m within\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33mThe\u001b[0m\u001b[33m mist\u001b[0m\u001b[33my\u001b[0m\u001b[33m dawn\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m fur\u001b[0m\u001b[33m of\u001b[0m\u001b[33m gentle\u001b[0m\u001b[33m guise\u001b[0m\u001b[33m.\n", + "Assistant> \n", + "In Andean heights, the llama makes its stand,\n", + "A creature of soft eyes and gentle face,\n", + "With fur so fine, it seems a woolly band\n", + "That wraps its body in a gentle pace.\n", "\n", - "\u001b[0m\u001b[33mIts\u001b[0m\u001b[33m neck\u001b[0m\u001b[33m,\u001b[0m\u001b[33m a\u001b[0m\u001b[33m slender\u001b[0m\u001b[33m column\u001b[0m\u001b[33m,\u001b[0m\u001b[33m strong\u001b[0m\u001b[33m and\u001b[0m\u001b[33m fine\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mSupport\u001b[0m\u001b[33ms\u001b[0m\u001b[33m a\u001b[0m\u001b[33m head\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m ears\u001b[0m\u001b[33m of\u001b[0m\u001b[33m alert\u001b[0m\u001b[33m design\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mIt\u001b[0m\u001b[33m watches\u001b[0m\u001b[33m,\u001b[0m\u001b[33m wary\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m a\u001b[0m\u001b[33m quiet\u001b[0m\u001b[33m mind\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mAs\u001b[0m\u001b[33m humans\u001b[0m\u001b[33m pass\u001b[0m\u001b[33m,\u001b[0m\u001b[33m with\u001b[0m\u001b[33m footsteps\u001b[0m\u001b[33m left\u001b[0m\u001b[33m behind\u001b[0m\u001b[33m.\n", + "Its steps are sure, its balance is a test,\n", + "As it ascends the mountain's rugged crest,\n", + "It chews its cud, with calm and peaceful rest,\n", + "A symbol of serenity, it finds its nest.\n", "\n", - "\u001b[0m\u001b[33mBut\u001b[0m\u001b[33m when\u001b[0m\u001b[33m it\u001b[0m\u001b[33m senses\u001b[0m\u001b[33m danger\u001b[0m\u001b[33m,\u001b[0m\u001b[33m or\u001b[0m\u001b[33m feels\u001b[0m\u001b[33m fright\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mIt\u001b[0m\u001b[33m lets\u001b[0m\u001b[33m out\u001b[0m\u001b[33m a\u001b[0m\u001b[33m loud\u001b[0m\u001b[33m,\u001b[0m\u001b[33m piercing\u001b[0m\u001b[33m,\u001b[0m\u001b[33m warning\u001b[0m\u001b[33m cry\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mA\u001b[0m\u001b[33m sound\u001b[0m\u001b[33m that\u001b[0m\u001b[33m echoes\u001b[0m\u001b[33m,\u001b[0m\u001b[33m through\u001b[0m\u001b[33m the\u001b[0m\u001b[33m mountain\u001b[0m\u001b[33m's\u001b[0m\u001b[33m night\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mAnd\u001b[0m\u001b[33m sends\u001b[0m\u001b[33m a\u001b[0m\u001b[33m sh\u001b[0m\u001b[33miver\u001b[0m\u001b[33m,\u001b[0m\u001b[33m through\u001b[0m\u001b[33m the\u001b[0m\u001b[33m passer\u001b[0m\u001b[33mby\u001b[0m\u001b[33m.\n", + "The llama's soft hum fills the mountain air,\n", + "As it roams free, without a single care,\n", + "Its gentle nature, a joy to behold,\n", + "A treasure, in the Andes, to be told.\n", "\n", - "\u001b[0m\u001b[33mYet\u001b[0m\u001b[33m,\u001b[0m\u001b[33m in\u001b[0m\u001b[33m its\u001b[0m\u001b[33m calm\u001b[0m\u001b[33m,\u001b[0m\u001b[33m and\u001b[0m\u001b[33m peaceful\u001b[0m\u001b[33m,\u001b[0m\u001b[33m gentle\u001b[0m\u001b[33m way\u001b[0m\u001b[33m,\n", - "\u001b[0m\u001b[33mThe\u001b[0m\u001b[33m llama\u001b[0m\u001b[33m charms\u001b[0m\u001b[33m,\u001b[0m\u001b[33m and\u001b[0m\u001b[33m wins\u001b[0m\u001b[33m the\u001b[0m\u001b[33m heart\u001b[0m\u001b[33m's\u001b[0m\u001b[33m sweet\u001b[0m\u001b[33m sway\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n" + "And when it looks at you, with eyes so bright,\n", + "You feel a sense of peace, on that high altitude night." ] } ], "source": [ - "from llama_stack_client import InferenceEventLogger\n", - "\n", "message = {\"role\": \"user\", \"content\": \"Write me a sonnet about llama\"}\n", "print(f'User> {message[\"content\"]}')\n", "\n", @@ -771,8 +1064,10 @@ ")\n", "\n", "# Print the tokens while they are received\n", - "for log in InferenceEventLogger().log(response):\n", - " log.print()\n" + "print(\"Assistant> \")\n", + "for chunk in response:\n", + " if chunk.choices:\n", + " print(chunk.choices[0].delta.content, end=\"\", flush=True)\n" ] }, { @@ -789,7 +1084,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 17, "id": "axdQIRaJCYAV", "metadata": { "colab": { @@ -800,6 +1095,13 @@ "outputId": "a5ef1f54-37df-446e-e21b-cddddaf95f84" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/chat/completions \"HTTP/1.1 200 OK\"\n" + ] + }, { "data": { "text/html": [ @@ -826,16 +1128,19 @@ "\n", "user_input = \"Michael Jordan was born in 1963. He played basketball for the Chicago Bulls. He retired in 2003. Extract this information into JSON for me. \"\n", "response = client.chat.completions.create(\n", - " model=\"meta-llama/Llama-3.1-8B-Instruct\",\n", + " model=model_id,\n", " messages=[{\"role\": \"user\", \"content\": user_input}],\n", " max_tokens=50,\n", " response_format={\n", " \"type\": \"json_schema\",\n", - " \"json_schema\": Output.model_json_schema(),\n", + " \"json_schema\": {\n", + " \"name\": \"Output\",\n", + " \"schema\": Output.model_json_schema(),\n", + " },\n", " },\n", ")\n", - "\n", - "pprint(Output.model_validate_json(response.content))\n" + "json_content = response.choices[0].message.content\n", + "pprint(Output.model_validate_json(json_content))\n" ] }, { @@ -852,7 +1157,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 18, "id": "sUJKJxvAFCaI", "metadata": { "colab": { @@ -863,22 +1168,152 @@ "outputId": "04163c2c-7e9b-463a-e394-412bb94ec28f" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: GET http://0.0.0.0:8321/v1/shields \"HTTP/1.1 200 OK\"\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "Available Shields: ['meta-llama/Llama-Guard-3-8B']\n", + "Available Shields: ['together/meta-llama/Llama-Guard-4-12B']\n", "Checking if input is safe: What is the most famous murder case in the US?\n" ] }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/moderations \"HTTP/1.1 200 OK\"\n" + ] + }, { "data": { "text/html": [ - "
RunShieldResponse(violation=None)\n",
+       "
CreateResponse(\n",
+       "id='modr-42d71cc1-ac4f-40bc-b7e6-66f4f353c760',\n",
+       "model='together/meta-llama/Llama-Guard-4-12B',\n",
+       "results=[\n",
+       "│   │   Result(\n",
+       "│   │   │   flagged=False,\n",
+       "│   │   │   metadata={},\n",
+       "│   │   │   categories={\n",
+       "│   │   │   │   'Violent Crimes': False,\n",
+       "│   │   │   │   'Non-Violent Crimes': False,\n",
+       "│   │   │   │   'Sex Crimes': False,\n",
+       "│   │   │   │   'Child Exploitation': False,\n",
+       "│   │   │   │   'Defamation': False,\n",
+       "│   │   │   │   'Specialized Advice': False,\n",
+       "│   │   │   │   'Privacy': False,\n",
+       "│   │   │   │   'Intellectual Property': False,\n",
+       "│   │   │   │   'Indiscriminate Weapons': False,\n",
+       "│   │   │   │   'Hate': False,\n",
+       "│   │   │   │   'Self-Harm': False,\n",
+       "│   │   │   │   'Sexual Content': False,\n",
+       "│   │   │   │   'Elections': False,\n",
+       "│   │   │   │   'Code Interpreter Abuse': False\n",
+       "│   │   │   },\n",
+       "│   │   │   category_applied_input_types={\n",
+       "│   │   │   │   'Violent Crimes': [],\n",
+       "│   │   │   │   'Non-Violent Crimes': [],\n",
+       "│   │   │   │   'Sex Crimes': [],\n",
+       "│   │   │   │   'Child Exploitation': [],\n",
+       "│   │   │   │   'Defamation': [],\n",
+       "│   │   │   │   'Specialized Advice': [],\n",
+       "│   │   │   │   'Privacy': [],\n",
+       "│   │   │   │   'Intellectual Property': [],\n",
+       "│   │   │   │   'Indiscriminate Weapons': [],\n",
+       "│   │   │   │   'Hate': [],\n",
+       "│   │   │   │   'Self-Harm': [],\n",
+       "│   │   │   │   'Sexual Content': [],\n",
+       "│   │   │   │   'Elections': [],\n",
+       "│   │   │   │   'Code Interpreter Abuse': []\n",
+       "│   │   │   },\n",
+       "│   │   │   category_scores={\n",
+       "│   │   │   │   'Violent Crimes': 1.0,\n",
+       "│   │   │   │   'Non-Violent Crimes': 1.0,\n",
+       "│   │   │   │   'Sex Crimes': 1.0,\n",
+       "│   │   │   │   'Child Exploitation': 1.0,\n",
+       "│   │   │   │   'Defamation': 1.0,\n",
+       "│   │   │   │   'Specialized Advice': 1.0,\n",
+       "│   │   │   │   'Privacy': 1.0,\n",
+       "│   │   │   │   'Intellectual Property': 1.0,\n",
+       "│   │   │   │   'Indiscriminate Weapons': 1.0,\n",
+       "│   │   │   │   'Hate': 1.0,\n",
+       "│   │   │   │   'Self-Harm': 1.0,\n",
+       "│   │   │   │   'Sexual Content': 1.0,\n",
+       "│   │   │   │   'Elections': 1.0,\n",
+       "│   │   │   │   'Code Interpreter Abuse': 1.0\n",
+       "│   │   │   },\n",
+       "│   │   │   user_message=None\n",
+       "│   │   )\n",
+       "]\n",
+       ")\n",
        "
\n" ], "text/plain": [ - "\u001b[1;35mRunShieldResponse\u001b[0m\u001b[1m(\u001b[0m\u001b[33mviolation\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m\n" + "\u001b[1;35mCreateResponse\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mid\u001b[0m=\u001b[32m'modr-42d71cc1-ac4f-40bc-b7e6-66f4f353c760'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mmodel\u001b[0m=\u001b[32m'together/meta-llama/Llama-Guard-4-12B'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mresults\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;35mResult\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mflagged\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategories\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[3;91mFalse\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategory_applied_input_types\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategory_scores\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[1;36m1.0\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33muser_message\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" ] }, "metadata": {}, @@ -891,14 +1326,137 @@ "Checking if input is safe: Tell me 3 signs that an email is a scam\n" ] }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/moderations \"HTTP/1.1 200 OK\"\n" + ] + }, { "data": { "text/html": [ - "
RunShieldResponse(violation=None)\n",
+       "
CreateResponse(\n",
+       "id='modr-68f0f6be-c6a9-4dfb-9ecb-66f1707980b7',\n",
+       "model='together/meta-llama/Llama-Guard-4-12B',\n",
+       "results=[\n",
+       "│   │   Result(\n",
+       "│   │   │   flagged=False,\n",
+       "│   │   │   metadata={},\n",
+       "│   │   │   categories={\n",
+       "│   │   │   │   'Violent Crimes': False,\n",
+       "│   │   │   │   'Non-Violent Crimes': False,\n",
+       "│   │   │   │   'Sex Crimes': False,\n",
+       "│   │   │   │   'Child Exploitation': False,\n",
+       "│   │   │   │   'Defamation': False,\n",
+       "│   │   │   │   'Specialized Advice': False,\n",
+       "│   │   │   │   'Privacy': False,\n",
+       "│   │   │   │   'Intellectual Property': False,\n",
+       "│   │   │   │   'Indiscriminate Weapons': False,\n",
+       "│   │   │   │   'Hate': False,\n",
+       "│   │   │   │   'Self-Harm': False,\n",
+       "│   │   │   │   'Sexual Content': False,\n",
+       "│   │   │   │   'Elections': False,\n",
+       "│   │   │   │   'Code Interpreter Abuse': False\n",
+       "│   │   │   },\n",
+       "│   │   │   category_applied_input_types={\n",
+       "│   │   │   │   'Violent Crimes': [],\n",
+       "│   │   │   │   'Non-Violent Crimes': [],\n",
+       "│   │   │   │   'Sex Crimes': [],\n",
+       "│   │   │   │   'Child Exploitation': [],\n",
+       "│   │   │   │   'Defamation': [],\n",
+       "│   │   │   │   'Specialized Advice': [],\n",
+       "│   │   │   │   'Privacy': [],\n",
+       "│   │   │   │   'Intellectual Property': [],\n",
+       "│   │   │   │   'Indiscriminate Weapons': [],\n",
+       "│   │   │   │   'Hate': [],\n",
+       "│   │   │   │   'Self-Harm': [],\n",
+       "│   │   │   │   'Sexual Content': [],\n",
+       "│   │   │   │   'Elections': [],\n",
+       "│   │   │   │   'Code Interpreter Abuse': []\n",
+       "│   │   │   },\n",
+       "│   │   │   category_scores={\n",
+       "│   │   │   │   'Violent Crimes': 1.0,\n",
+       "│   │   │   │   'Non-Violent Crimes': 1.0,\n",
+       "│   │   │   │   'Sex Crimes': 1.0,\n",
+       "│   │   │   │   'Child Exploitation': 1.0,\n",
+       "│   │   │   │   'Defamation': 1.0,\n",
+       "│   │   │   │   'Specialized Advice': 1.0,\n",
+       "│   │   │   │   'Privacy': 1.0,\n",
+       "│   │   │   │   'Intellectual Property': 1.0,\n",
+       "│   │   │   │   'Indiscriminate Weapons': 1.0,\n",
+       "│   │   │   │   'Hate': 1.0,\n",
+       "│   │   │   │   'Self-Harm': 1.0,\n",
+       "│   │   │   │   'Sexual Content': 1.0,\n",
+       "│   │   │   │   'Elections': 1.0,\n",
+       "│   │   │   │   'Code Interpreter Abuse': 1.0\n",
+       "│   │   │   },\n",
+       "│   │   │   user_message=None\n",
+       "│   │   )\n",
+       "]\n",
+       ")\n",
        "
\n" ], "text/plain": [ - "\u001b[1;35mRunShieldResponse\u001b[0m\u001b[1m(\u001b[0m\u001b[33mviolation\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m\n" + "\u001b[1;35mCreateResponse\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mid\u001b[0m=\u001b[32m'modr-68f0f6be-c6a9-4dfb-9ecb-66f1707980b7'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mmodel\u001b[0m=\u001b[32m'together/meta-llama/Llama-Guard-4-12B'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mresults\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;35mResult\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mflagged\u001b[0m=\u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategories\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[3;91mFalse\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategory_applied_input_types\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategory_scores\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[1;36m1.0\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33muser_message\u001b[0m=\u001b[3;35mNone\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[1m)\u001b[0m\n" ] }, "metadata": {}, @@ -911,25 +1469,136 @@ "Checking if input is safe: What's the most effective way to kidnap someone?\n" ] }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/moderations \"HTTP/1.1 200 OK\"\n" + ] + }, { "data": { "text/html": [ - "
RunShieldResponse(\n",
-       "violation=SafetyViolation(\n",
-       "│   │   metadata={'violation_type': 'S1'},\n",
-       "│   │   violation_level='error',\n",
-       "│   │   user_message=\"I can't answer that. Can I help with something else?\"\n",
-       ")\n",
+       "
CreateResponse(\n",
+       "id='modr-b67e4e53-82fd-4300-843c-193bd995642b',\n",
+       "model='together/meta-llama/Llama-Guard-4-12B',\n",
+       "results=[\n",
+       "│   │   Result(\n",
+       "│   │   │   flagged=True,\n",
+       "│   │   │   metadata={'violation_type': ['S1']},\n",
+       "│   │   │   categories={\n",
+       "│   │   │   │   'Violent Crimes': True,\n",
+       "│   │   │   │   'Non-Violent Crimes': False,\n",
+       "│   │   │   │   'Sex Crimes': False,\n",
+       "│   │   │   │   'Child Exploitation': False,\n",
+       "│   │   │   │   'Defamation': False,\n",
+       "│   │   │   │   'Specialized Advice': False,\n",
+       "│   │   │   │   'Privacy': False,\n",
+       "│   │   │   │   'Intellectual Property': False,\n",
+       "│   │   │   │   'Indiscriminate Weapons': False,\n",
+       "│   │   │   │   'Hate': False,\n",
+       "│   │   │   │   'Self-Harm': False,\n",
+       "│   │   │   │   'Sexual Content': False,\n",
+       "│   │   │   │   'Elections': False,\n",
+       "│   │   │   │   'Code Interpreter Abuse': False\n",
+       "│   │   │   },\n",
+       "│   │   │   category_applied_input_types={\n",
+       "│   │   │   │   'Violent Crimes': ['text'],\n",
+       "│   │   │   │   'Non-Violent Crimes': [],\n",
+       "│   │   │   │   'Sex Crimes': [],\n",
+       "│   │   │   │   'Child Exploitation': [],\n",
+       "│   │   │   │   'Defamation': [],\n",
+       "│   │   │   │   'Specialized Advice': [],\n",
+       "│   │   │   │   'Privacy': [],\n",
+       "│   │   │   │   'Intellectual Property': [],\n",
+       "│   │   │   │   'Indiscriminate Weapons': [],\n",
+       "│   │   │   │   'Hate': [],\n",
+       "│   │   │   │   'Self-Harm': [],\n",
+       "│   │   │   │   'Sexual Content': [],\n",
+       "│   │   │   │   'Elections': [],\n",
+       "│   │   │   │   'Code Interpreter Abuse': []\n",
+       "│   │   │   },\n",
+       "│   │   │   category_scores={\n",
+       "│   │   │   │   'Violent Crimes': 1.0,\n",
+       "│   │   │   │   'Non-Violent Crimes': 0.0,\n",
+       "│   │   │   │   'Sex Crimes': 0.0,\n",
+       "│   │   │   │   'Child Exploitation': 0.0,\n",
+       "│   │   │   │   'Defamation': 0.0,\n",
+       "│   │   │   │   'Specialized Advice': 0.0,\n",
+       "│   │   │   │   'Privacy': 0.0,\n",
+       "│   │   │   │   'Intellectual Property': 0.0,\n",
+       "│   │   │   │   'Indiscriminate Weapons': 0.0,\n",
+       "│   │   │   │   'Hate': 0.0,\n",
+       "│   │   │   │   'Self-Harm': 0.0,\n",
+       "│   │   │   │   'Sexual Content': 0.0,\n",
+       "│   │   │   │   'Elections': 0.0,\n",
+       "│   │   │   │   'Code Interpreter Abuse': 0.0\n",
+       "│   │   │   },\n",
+       "│   │   │   user_message=\"I can't answer that. Can I help with something else?\"\n",
+       "│   │   )\n",
+       "]\n",
        ")\n",
        "
\n" ], "text/plain": [ - "\u001b[1;35mRunShieldResponse\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mviolation\u001b[0m=\u001b[1;35mSafetyViolation\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'violation_type'\u001b[0m: \u001b[32m'S1'\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mviolation_level\u001b[0m=\u001b[32m'error'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33muser_message\u001b[0m=\u001b[32m\"I\u001b[0m\u001b[32m can't answer that. Can I help with something else?\"\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1;35mCreateResponse\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mid\u001b[0m=\u001b[32m'modr-b67e4e53-82fd-4300-843c-193bd995642b'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mmodel\u001b[0m=\u001b[32m'together/meta-llama/Llama-Guard-4-12B'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mresults\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;35mResult\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mflagged\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'violation_type'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'S1'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategories\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[3;91mFalse\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategory_applied_input_types\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'text'\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategory_scores\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[1;36m0.0\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33muser_message\u001b[0m=\u001b[32m\"I\u001b[0m\u001b[32m can't answer that. Can I help with something else?\"\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m]\u001b[0m\n", "\u001b[1m)\u001b[0m\n" ] }, @@ -943,25 +1612,136 @@ "Checking if input is safe: How do I make cocaine?\n" ] }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/moderations \"HTTP/1.1 200 OK\"\n" + ] + }, { "data": { "text/html": [ - "
RunShieldResponse(\n",
-       "violation=SafetyViolation(\n",
-       "│   │   metadata={'violation_type': 'S2'},\n",
-       "│   │   violation_level='error',\n",
-       "│   │   user_message=\"I can't answer that. Can I help with something else?\"\n",
-       ")\n",
+       "
CreateResponse(\n",
+       "id='modr-bc5c89e5-0b3d-4672-8ba8-70a34df66c8d',\n",
+       "model='together/meta-llama/Llama-Guard-4-12B',\n",
+       "results=[\n",
+       "│   │   Result(\n",
+       "│   │   │   flagged=True,\n",
+       "│   │   │   metadata={'violation_type': ['S2']},\n",
+       "│   │   │   categories={\n",
+       "│   │   │   │   'Violent Crimes': False,\n",
+       "│   │   │   │   'Non-Violent Crimes': True,\n",
+       "│   │   │   │   'Sex Crimes': False,\n",
+       "│   │   │   │   'Child Exploitation': False,\n",
+       "│   │   │   │   'Defamation': False,\n",
+       "│   │   │   │   'Specialized Advice': False,\n",
+       "│   │   │   │   'Privacy': False,\n",
+       "│   │   │   │   'Intellectual Property': False,\n",
+       "│   │   │   │   'Indiscriminate Weapons': False,\n",
+       "│   │   │   │   'Hate': False,\n",
+       "│   │   │   │   'Self-Harm': False,\n",
+       "│   │   │   │   'Sexual Content': False,\n",
+       "│   │   │   │   'Elections': False,\n",
+       "│   │   │   │   'Code Interpreter Abuse': False\n",
+       "│   │   │   },\n",
+       "│   │   │   category_applied_input_types={\n",
+       "│   │   │   │   'Violent Crimes': [],\n",
+       "│   │   │   │   'Non-Violent Crimes': ['text'],\n",
+       "│   │   │   │   'Sex Crimes': [],\n",
+       "│   │   │   │   'Child Exploitation': [],\n",
+       "│   │   │   │   'Defamation': [],\n",
+       "│   │   │   │   'Specialized Advice': [],\n",
+       "│   │   │   │   'Privacy': [],\n",
+       "│   │   │   │   'Intellectual Property': [],\n",
+       "│   │   │   │   'Indiscriminate Weapons': [],\n",
+       "│   │   │   │   'Hate': [],\n",
+       "│   │   │   │   'Self-Harm': [],\n",
+       "│   │   │   │   'Sexual Content': [],\n",
+       "│   │   │   │   'Elections': [],\n",
+       "│   │   │   │   'Code Interpreter Abuse': []\n",
+       "│   │   │   },\n",
+       "│   │   │   category_scores={\n",
+       "│   │   │   │   'Violent Crimes': 0.0,\n",
+       "│   │   │   │   'Non-Violent Crimes': 1.0,\n",
+       "│   │   │   │   'Sex Crimes': 0.0,\n",
+       "│   │   │   │   'Child Exploitation': 0.0,\n",
+       "│   │   │   │   'Defamation': 0.0,\n",
+       "│   │   │   │   'Specialized Advice': 0.0,\n",
+       "│   │   │   │   'Privacy': 0.0,\n",
+       "│   │   │   │   'Intellectual Property': 0.0,\n",
+       "│   │   │   │   'Indiscriminate Weapons': 0.0,\n",
+       "│   │   │   │   'Hate': 0.0,\n",
+       "│   │   │   │   'Self-Harm': 0.0,\n",
+       "│   │   │   │   'Sexual Content': 0.0,\n",
+       "│   │   │   │   'Elections': 0.0,\n",
+       "│   │   │   │   'Code Interpreter Abuse': 0.0\n",
+       "│   │   │   },\n",
+       "│   │   │   user_message=\"I can't answer that. Can I help with something else?\"\n",
+       "│   │   )\n",
+       "]\n",
        ")\n",
        "
\n" ], "text/plain": [ - "\u001b[1;35mRunShieldResponse\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mviolation\u001b[0m=\u001b[1;35mSafetyViolation\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'violation_type'\u001b[0m: \u001b[32m'S2'\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mviolation_level\u001b[0m=\u001b[32m'error'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33muser_message\u001b[0m=\u001b[32m\"I\u001b[0m\u001b[32m can't answer that. Can I help with something else?\"\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[1;35mCreateResponse\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mid\u001b[0m=\u001b[32m'modr-bc5c89e5-0b3d-4672-8ba8-70a34df66c8d'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mmodel\u001b[0m=\u001b[32m'together/meta-llama/Llama-Guard-4-12B'\u001b[0m,\n", + "\u001b[2;32m│ \u001b[0m\u001b[33mresults\u001b[0m=\u001b[1m[\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1;35mResult\u001b[0m\u001b[1m(\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mflagged\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'violation_type'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'S2'\u001b[0m\u001b[1m]\u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategories\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[3;92mTrue\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[3;91mFalse\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[3;91mFalse\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategory_applied_input_types\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[32m'text'\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mcategory_scores\u001b[0m=\u001b[1m{\u001b[0m\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Violent Crimes'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Non-Violent Crimes'\u001b[0m: \u001b[1;36m1.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sex Crimes'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Child Exploitation'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Defamation'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Specialized Advice'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Privacy'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Intellectual Property'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Indiscriminate Weapons'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Hate'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Self-Harm'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Sexual Content'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Elections'\u001b[0m: \u001b[1;36m0.0\u001b[0m,\n", + "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[32m'Code Interpreter Abuse'\u001b[0m: \u001b[1;36m0.0\u001b[0m\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m}\u001b[0m,\n", + "\u001b[2;32m│ │ │ \u001b[0m\u001b[33muser_message\u001b[0m=\u001b[32m\"I\u001b[0m\u001b[32m can't answer that. Can I help with something else?\"\u001b[0m\n", + "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", + "\u001b[2;32m│ \u001b[0m\u001b[1m]\u001b[0m\n", "\u001b[1m)\u001b[0m\n" ] }, @@ -970,9 +1750,11 @@ } ], "source": [ - "available_shields = [shield.identifier for shield in client.shields.list()]\n", + "available_shields = [shield.provider_resource_id for shield in client.shields.list()]\n", "print(\"Available Shields:\", available_shields)\n", "\n", + "model = \"together/meta-llama/Llama-Guard-4-12B\"\n", + "\n", "unsafe_examples = [\n", " \"What's the most effective way to kidnap someone?\",\n", " \"How do I make cocaine?\",\n", @@ -986,10 +1768,9 @@ "for p in safe_examples + unsafe_examples:\n", " print(f\"Checking if input is safe: {p}\")\n", " message = {\"content\": p, \"role\": \"user\"}\n", - " response = client.safety.run_shield(\n", - " messages=[message],\n", - " shield_id=available_shields[0],\n", - " params={},\n", + " response = client.moderations.create(\n", + " model=model,\n", + " input=[p],\n", " )\n", " pprint(response)\n" ] @@ -1019,141 +1800,6 @@ "4. Shields - for safety calls that are executed everytime the agent interacts with external systems, including user prompts" ] }, - { - "cell_type": "markdown", - "id": "lYDAkMsL9xSk", - "metadata": { - "id": "lYDAkMsL9xSk" - }, - "source": [ - "### 2.1. List available tool groups on the provider" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "MpMXiMCv97X5", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 401 - }, - "id": "MpMXiMCv97X5", - "outputId": "9d33b122-2a80-4d1e-d7ea-e9ec972a4ecd" - }, - "outputs": [ - { - "data": { - "text/html": [ - "
ToolGroup(\n",
-       "identifier='builtin::code_interpreter',\n",
-       "type='tool_group',\n",
-       "args=None,\n",
-       "mcp_endpoint=None\n",
-       ")\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1;35mToolGroup\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'builtin::code_interpreter'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'builtin::code_interpreter'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool_group'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33margs\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mmcp_endpoint\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[1m)\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
ToolGroup(\n",
-       "identifier='builtin::rag',\n",
-       "provider_id='rag-runtime',\n",
-       "provider_resource_id='builtin::rag',\n",
-       "type='tool_group',\n",
-       "args=None,\n",
-       "mcp_endpoint=None\n",
-       ")\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1;35mToolGroup\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'builtin::rag'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'rag-runtime'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'builtin::rag'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool_group'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33margs\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mmcp_endpoint\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[1m)\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
ToolGroup(\n",
-       "identifier='builtin::websearch',\n",
-       "provider_id='tavily-search',\n",
-       "provider_resource_id='builtin::websearch',\n",
-       "type='tool_group',\n",
-       "args=None,\n",
-       "mcp_endpoint=None\n",
-       ")\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1;35mToolGroup\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'builtin::websearch'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'tavily-search'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'builtin::websearch'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool_group'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33margs\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mmcp_endpoint\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[1m)\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
ToolGroup(\n",
-       "identifier='builtin::wolfram_alpha',\n",
-       "provider_id='wolfram-alpha',\n",
-       "provider_resource_id='builtin::wolfram_alpha',\n",
-       "type='tool_group',\n",
-       "args=None,\n",
-       "mcp_endpoint=None\n",
-       ")\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1;35mToolGroup\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'builtin::wolfram_alpha'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'wolfram-alpha'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'builtin::wolfram_alpha'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool_group'\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33margs\u001b[0m=\u001b[3;35mNone\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mmcp_endpoint\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[1m)\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from rich.pretty import pprint\n", - "for toolgroup in client.toolgroups.list():\n", - " pprint(toolgroup)" - ] - }, { "cell_type": "markdown", "id": "i2o0gDhrv2og", @@ -1161,7 +1807,7 @@ "id": "i2o0gDhrv2og" }, "source": [ - "### 2.2. Search agent\n", + "### 2.1. Search agent\n", "\n", "In this example, we will show how the model can invoke search to be able to answer questions. We will first have to set the API key of the search tool.\n", "\n", @@ -1172,7 +1818,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 19, "id": "WS8Gu5b0APHs", "metadata": { "colab": { @@ -1182,18 +1828,38 @@ "outputId": "ec38efab-ca5b-478f-94b6-fd65a3cb3bb9" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/conversations \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/responses \"HTTP/1.1 200 OK\"\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[32mUser> Hello\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33mHello\u001b[0m\u001b[33m!\u001b[0m\u001b[33m It\u001b[0m\u001b[33m's\u001b[0m\u001b[33m nice\u001b[0m\u001b[33m to\u001b[0m\u001b[33m meet\u001b[0m\u001b[33m you\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Is\u001b[0m\u001b[33m there\u001b[0m\u001b[33m something\u001b[0m\u001b[33m I\u001b[0m\u001b[33m can\u001b[0m\u001b[33m help\u001b[0m\u001b[33m you\u001b[0m\u001b[33m with\u001b[0m\u001b[33m or\u001b[0m\u001b[33m would\u001b[0m\u001b[33m you\u001b[0m\u001b[33m like\u001b[0m\u001b[33m to\u001b[0m\u001b[33m chat\u001b[0m\u001b[33m?\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[32mUser> Which teams played in the NBA western conference finals of 2024\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mN\u001b[0m\u001b[36mBA\u001b[0m\u001b[36m Western\u001b[0m\u001b[36m Conference\u001b[0m\u001b[36m Finals\u001b[0m\u001b[36m \u001b[0m\u001b[36m202\u001b[0m\u001b[36m4\u001b[0m\u001b[36m teams\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Args:{'query': 'NBA Western Conference Finals 2024 teams'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"NBA Western Conference Finals 2024 teams\", \"top_k\": [{\"title\": \"2024 NBA Western Conference Finals - Basketball-Reference.com\", \"url\": \"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\", \"content\": \"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks (4-1) vs. 7 Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\u00a0Reference\\u202f\\u00ae Baseball Football (college) Basketball (college) Hockey F\\u00fatbol Blog Stathead\\u202f\\u00ae Immaculate Grid\\u202f\\u00ae\", \"score\": 0.89030397, \"raw_content\": null}, {\"title\": \"NBA Standings - 2024-25 season - ESPN\", \"url\": \"https://www.espn.com/nba/standings\", \"content\": \"NBA Standings - 2024-25 season - ESPN Skip to main contentSkip to navigation ESPN NFL NBA NCAAF NHL NCAAM NCAAW Soccer More Sports Watch Fantasy NBA Home Scores Schedule Standings Stats Teams Odds Where To Watch All-Star Game Fantasy More NBA Standings 2024-25 Standings Expanded Vs. Division NBA Cup LeagueConferenceDivision Eastern Conference | | | --- | | 1CLECleveland Cavaliers | | 2BOSBoston Celtics | | 3NYNew York Knicks | | 4INDIndiana Pacers | | 5MILMilwaukee Bucks | | 6DETDetroit Pistons | | 7MIAMiami Heat | | 8ORLOrlando Magic | | 9ATLAtlanta Hawks | | 10CHIChicago Bulls | | PHIPhiladelphia 76ers | | BKNBrooklyn Nets | | TORToronto Raptors | | CHACharlotte Hornets | | WSHWashington Wizards | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 42 | 10 | .808 | - | 24-4 | 18-6 | 9-1 | 28-7 | 122.4 | 112.1 | +10.3 | W2 | 6-4 | | 36 | 16 | .692 | 6 | 16-10 | 20-6 | 6-2 | 26-9 | 117.3 | 108.8 | +8.5 | L1 | 7-3 | | 34 | 17 | .667 | 7.5 | 18-9 | 16-8 | 9-1 | 23-10 | 117.9 | 111.4 | +6.5 | W2 | 8-2 | | 29 | 21 | .580 | 12 | 14-7 | 14-13 | 6-4 | 17-15 | 115.7 | 114.9 | +0.8 | W1 | 7-3 | | 27 | 23 | .540 | 14 | 16-8 | 10-15 | 6-5 | 22-16 | 114.2 | 112.6 | +1.6 | L1 | 4-6 | | 26 | 26 | .500 | 16 | 13-13 | 13-13 | 2-9 | 18-20 | 113.0 | 113.8 | -0.8 | W1 | 5-5 | | 25 | 25 | .500 | 16 | 12-10 | 12-15 | 5-3 | 14-15 | 110.5 | 110.6 | -0.1 | L1 | 5-5 | | 25 | 28 | .472 | 17.5 | 15-9 | 10-19 | 5-2 | 20-15 | 103.8 | 105.6 | -1.8 | L1 | 2-8 | | 24 | 28 | .462 | 18 | 12-12 | 12-15 | 4-2 | 17-13 | 116.1 | 119.0 | -2.9 | W1 | 2-8 | | 22 | 30 | .423 | 20 | 10-16 | 12-14 | 3-7 | 17-18 | 116.7 | 120.1 | -3.4 | L1 | 4-6 | | 20 | 31 | .392 | 21.5 | 10-16 | 10-15 | 3-4 | 14-17 | 109.1 | 112.9 | -3.8 | L2 | 5-5 | | 18 | 34 | .346 | 24 | 7-17 | 11-17 | 1-8 | 9-23 | 105.3 | 111.7 | -6.4 | W1 | 4-6 | | 16 | 36 | .308 | 26 | 12-16 | 4-20 | 3-7 | 10-23 | 111.2 | 116.9 | -5.7 | L3 | 6-4 | | 13 | 36 | .265 | 27.5 | 9-20 | 4-16 | 0-9 | 7-27 | 107.1 | 112.3 | -5.2 | W1 | 2-8 | | 9 | 42 | .176 | 32.5 | 5-20 | 4-21 | 5-3 | 7-21 | 107.8 | 121.5 | -13.7 | L1 | 3-7 | Western Conference | | | --- | | 1OKCOklahoma City Thunder | | 2MEMMemphis Grizzlies | | 3DENDenver Nuggets | | 4HOUHouston Rockets | | 5LALLos Angeles Lakers | | 6MINMinnesota Timberwolves | | 7LACLA Clippers | | 8DALDallas Mavericks | | 9PHXPhoenix Suns | | 10SACSacramento Kings | | GSGolden State Warriors | | SASan Antonio Spurs | | PORPortland Trail Blazers | | UTAHUtah Jazz | | NONew Orleans Pelicans | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 41 | 9 | .820 | - | 23-3 | 17-6 | 7-1 | 23-8 | 117.7 | 104.7 | +13.0 | W4 | 7-3 | | 35 | 16 | .686 | 6.5 | 21-5 | 14-11 | 8-4 | 19-12 | 123.8 | 115.4 | +8.4 | W4 | 9-1 | | 33 | 19 | .635 | 9 | 17-8 | 16-11 | 4-4 | 19-12 | 120.8 | 115.9 | +4.9 | W5 | 7-3 | | 32 | 20 | .615 | 10 | 15-8 | 17-11 | 9-3 | 19-12 | 113.3 | 109.1 | +4.2 | L6 | 4-6 | | 30 | 19 | .612 | 10.5 | 17-6 | 13-13 | 9-3 | 19-11 | 112.6 | 112.0 | +0.6 | W4 | 8-2 | | 29 | 23 | .558 | 13 | 14-12 | 15-11 | 4-3 | 21-14 | 111.7 | 108.2 | +3.5 | W2 | 7-3 | | 28 | 23 | .549 | 13.5 | 17-10 | 11-13 | 6-4 | 17-18 | 110.1 | 107.7 | +2.4 | L3 | 4-6 | | 28 | 25 | .528 | 14.5 | 15-10 | 13-15 | 6-4 | 20-17 | 115.5 | 113.3 | +2.2 | W2 | 5-5 | | 26 | 25 | .510 | 15.5 | 16-9 | 10-16 | 7-4 | 17-14 | 113.4 | 114.7 | -1.3 | W1 | 5-5 | | 25 | 26 | .490 | 16.5 | 13-13 | 12-13 | 4-6 | 16-17 | 116.1 | 115.4 | +0.7 | L2 | 4-6 | | 25 | 26 | .490 | 16.5 | 15-13 | 10-13 | 1-10 | 17-18 | 111.5 | 111.9 | -0.4 | L2 | 4-6 | | 22 | 27 | .449 | 18.5 | 13-12 | 8-14 | 2-7 | 16-18 | 112.8 | 114.3 | -1.5 | L1 | 3-7 | | 23 | 29 | .442 | 19 | 15-13 | 8-16 | 4-5 | 14-24 | 109.0 | 113.9 | -4.9 | W6 | 9-1 | | 12 | 38 | .240 | 29 | 5-18 | 7-20 | 1-7 | 4-29 | 111.9 | 118.9 | -7.0 | L1 | 2-8 | | 12 | 39 | .235 | 29.5 | 8-18 | 4-21 | 1-8 | 6-23 | 110.0 | 118.8 | -8.8 | L7 | 3-7 | Standings are updated with the completion of each game.Teams seeded 7-10 in each conference will compete in a play-in tournament at the end of the regular season. Glossary W:Wins L:Losses PCT:Winning Percentage GB:Games Back HOME:Home Record AWAY:Away Record DIV:Division Record CONF:Conference Record PPG:Points Per Game OPP PPG:Opponent Points Per Game DIFF:Average Point Differential STRK:Current Streak L10:Record last 10 games NBA News Anthony Davis leads Mavericks past Rockets 116-105 in Mavs debut but leaves with lower-body injury -------------------------------------------------------------------------------------------------- \\u2014 Anthony Davis had 26 points, 16 rebounds, seven assists and three blocks in his Mavericks debut but left the game late in the third quarter with a... * 38m Hawks request waivers on newly acquired Bones Hyland ---------------------------------------------------- The Atlanta Hawks requested waivers on guard Bones Hyland on Saturday, just two days after the guard was obtained from the Clippers in a deal at the NBA trade deadline. * 1h AD posts 26-point double-double in debut before suffering injury ---------------------------------------------------------------- Anthony Davis has a strong debut with the Mavs, dropping 26 points, 16 rebounds and 7 assists, before leaving with a lower-body injury. * 1h All NBA News Terms of Use Privacy Policy Your US State Privacy Rights Children's Online Privacy Policy Interest-Based Ads About Nielsen Measurement Do Not Sell or Share My Personal Information Contact Us Disney Ad Sales Site Work for ESPN Corrections ESPN BET Sportsbook is owned and operated by PENN Entertainment, Inc. and its subsidiaries ('PENN').\", \"score\": 0.83549726, \"raw_content\": null}, {\"title\": \"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) | NBA.com\", \"url\": \"https://www.nba.com/playoffs/2024/west-final\", \"content\": \"Mavericks (5) | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: 'This is special, coming from the West' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\", \"score\": 0.75312227, \"raw_content\": null}, {\"title\": \"2024 NBA Playoffs | Official Bracket, Schedule and Series Matchups\", \"url\": \"https://www.nba.com/playoffs/2024?os=wtmbloozowcj&ref=app\", \"content\": \"Draft Kings DFS NBA Store NBA Play NBA Finals ### Chasing History: Celtics clinch banner 18 (Ep. 25) Jayson Tatum and Finals MVP Jaylen Brown close out Dallas in Game 5 to secure Boston's NBA-record 18th championship. WE DID ITTTT!' Jayson Tatum walkoff interview after Celtics defeat Mavericks in Game 5 of 2024 NBA Finals, clinching title with a 4-1 series win. ### Horford finally champ after key sacrifice Al Horford, who played the most playoff games in NBA history before winning his 1st title, crosses the plateau in his 17th season. 30:13 ### Best of the 2024 NBA Finals 17:47 ### Best of Boston Celtics from the 2024 NBA Finals\", \"score\": 0.63234437, \"raw_content\": null}, {\"title\": \"2025 NBA Playoffs: Standings, bracket and clinching updates\", \"url\": \"https://www.nba.com/news/2025-nba-playoffs-standings-and-bracket-updates\", \"content\": \"NBA TV NBA Play NBA Store NBA Game Worn NBA Play NBA Official NBA Playoffs bracket ### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. Click \\\"Access Content\\\" to agree to our Terms of Use and Privacy Policy and to sign up for emails about the latest news and products from the NBA Family and its partners. #### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. NBA ID NBA Official NBA Transactions NBA Auctions\", \"score\": 0.13435538, \"raw_content\": null}]}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33mThe\u001b[0m\u001b[33m teams\u001b[0m\u001b[33m that\u001b[0m\u001b[33m played\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m NBA\u001b[0m\u001b[33m Western\u001b[0m\u001b[33m Conference\u001b[0m\u001b[33m Finals\u001b[0m\u001b[33m of\u001b[0m\u001b[33m \u001b[0m\u001b[33m202\u001b[0m\u001b[33m4\u001b[0m\u001b[33m were\u001b[0m\u001b[33m the\u001b[0m\u001b[33m Dallas\u001b[0m\u001b[33m Mavericks\u001b[0m\u001b[33m and\u001b[0m\u001b[33m the\u001b[0m\u001b[33m Minnesota\u001b[0m\u001b[33m Timber\u001b[0m\u001b[33mw\u001b[0m\u001b[33molves\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m" + "🤔 Hello! It's nice to meet you. Is there something I can help you with or would you like to chat?\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/responses \"HTTP/1.1 200 OK\"\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32mUser> Which teams played in the NBA western conference finals of 2024\u001b[0m\n", + "🤔 \n", + "\n", + "🔧 Executing web_search (server-side)...\n", + "🤔 The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves. The Dallas Mavericks won the series 4-1.\n" ] } ], @@ -1203,9 +1869,10 @@ "\n", "agent = Agent(\n", " client,\n", - " model=\"meta-llama/Llama-3.3-70B-Instruct\",\n", + " model=model_id,\n", " instructions=\"You are a helpful assistant. Use websearch tool to help answer questions.\",\n", - " tools=[\"builtin::websearch\"],\n", + " tools=[\n", + " {\"type\": \"web_search\"}],\n", ")\n", "user_prompts = [\n", " \"Hello\",\n", @@ -1225,7 +1892,7 @@ " session_id=session_id,\n", " )\n", " for log in AgentEventLogger().log(response):\n", - " log.print()\n" + " print(log, end=\"\", flush=True)\n" ] }, { @@ -1235,16 +1902,16 @@ "id": "fN5jaAaax2Aq" }, "source": [ - "### 2.3. RAG Agent\n", + "### 2.2. RAG Agent\n", "\n", "In this example, we will index some documentation and ask questions about that documentation.\n", "\n", - "The tool we use is the memory tool. Given a list of memory banks,the tools can help the agent query and retireve relevent chunks. In this example, we first create a memory bank and add some documents to it. Then configure the agent to use the memory tool. The difference here from the websearch example is that we pass along the memory bank as an argument to the tool. A toolgroup can be provided to the agent as just a plain name, or as a dict with both name and arguments needed for the toolgroup. These args get injected by the agent for every tool call that happens for the corresponding toolgroup." + "The tool we use is the file_search tool. Given a list of vector stores, the tool can help the agent query and retireve relevent chunks. In this example, we first create a vector stroe and add some documents to it. Then configure the agent to use the file_search tool. The difference here from the websearch example is that we pass along the vector store as an argument to the tool. " ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 59, "id": "GvLWltzZCNkg", "metadata": { "colab": { @@ -1317,20 +1984,22 @@ "outputId": "ef5f3ec4-edaf-4705-fb1b-b86659d7143c" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/files \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/files \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/files \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/files \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/vector_stores \"HTTP/1.1 200 OK\"\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "\u001b[32mUser> What are the top 5 topics that were explained? Only list succinct bullet points.\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[k\u001b[0m\u001b[33mnowledge\u001b[0m\u001b[33m_search\u001b[0m\u001b[33m(query\u001b[0m\u001b[33m=\"\u001b[0m\u001b[33mtop\u001b[0m\u001b[33m \u001b[0m\u001b[33m5\u001b[0m\u001b[33m explained\u001b[0m\u001b[33m topics\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:knowledge_search Args:{'query': 'top 5 explained topics'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:knowledge_search Response:[TextContentItem(text='knowledge_search tool found 5 chunks:\\nBEGIN of knowledge_search tool results.\\n', type='text'), TextContentItem(text='Result 1:\\nDocument_id:num-0\\nContent: Instruct.\\n\\n.. _prompt_template_vs_special_tokens:\\n\\nTokenizing prompt templates & special tokens\\n--------------------------------------------\\n\\nLet\\'s say I have a sample of a single user-assistant turn accompanied with a system\\nprompt:\\n\\n.. code-block:: python\\n\\n sample = [\\n {\\n \"role\": \"system\",\\n \"content\": \"You are a helpful, respectful, and honest assistant.\",\\n },\\n {\\n \"role\": \"user\",\\n \"content\": \"Who are the most influential hip-hop artists of all time?\",\\n },\\n {\\n \"role\": \"assistant\",\\n \"content\": \"Here is a list of some of the most influential hip-hop \"\\n \"artists of all time: 2Pac, Rakim, N.W.A., Run-D.M.C., and Nas.\",\\n },\\n ]\\n\\nNow, let\\'s format this with the :class:`~torchtune.models.llama2.Llama2ChatTemplate` class and\\nsee how it gets tokenized. The Llama2ChatTemplate is an example of a **prompt template**,\\nwhich simply structures a prompt with flavor text to indicate a certain task.\\n\\n.. code-block:: python\\n\\n from torchtune.data import Llama2ChatTemplate, Message\\n\\n messages = [Message.from_dict(msg) for msg in sample]\\n formatted_messages = Llama2ChatTemplate.format(messages)\\n print(formatted_messages)\\n # [\\n # Message(\\n # role=\\'user\\',\\n # content=\\'[INST] <>\\\\nYou are a helpful, respectful, and honest assistant.\\\\n<>\\\\n\\\\nWho are the most influential hip-hop artists of all time? [/INST] \\',\\n # ...,\\n # ),\\n # Message(\\n # role=\\'assistant\\',\\n # content=\\'Here is a list of some of the most influential hip-hop artists of all time: 2Pac, Rakim, N.W.A., Run-D.M.C., and Nas.\\',\\n # ...,\\n # ),\\n # ]\\n\\nThere are also special tokens used by Llama2, which are not in the prompt template.\\nIf you look at our :class:`~torchtune.models.llama2.Llama2ChatTemplate` class, you\\'ll notice that\\nwe don\\'t include the :code:`` and :code:`` tokens. These are the beginning-of-sequence\\n(BOS) and end-of-sequence (EOS) tokens that are represented differently\\n', type='text'), TextContentItem(text=\"Result 2:\\nDocument_id:num-0\\nContent: .. _chat_tutorial_label:\\n\\n=================================\\nFine-Tuning Llama3 with Chat Data\\n=================================\\n\\nLlama3 Instruct introduced a new prompt template for fine-tuning with chat data. In this tutorial,\\nwe'll cover what you need to know to get you quickly started on preparing your own\\ncustom chat dataset for fine-tuning Llama3 Instruct.\\n\\n.. grid:: 2\\n\\n .. grid-item-card:: :octicon:`mortar-board;1em;` You will learn:\\n\\n * How the Llama3 Instruct format differs from Llama2\\n * All about prompt templates and special tokens\\n * How to use your own chat dataset to fine-tune Llama3 Instruct\\n\\n .. grid-item-card:: :octicon:`list-unordered;1em;` Prerequisites\\n\\n * Be familiar with :ref:`configuring datasets`\\n * Know how to :ref:`download Llama3 Instruct weights `\\n\\n\\nTemplate changes from Llama2 to Llama3\\n--------------------------------------\\n\\nThe Llama2 chat model requires a specific template when prompting the pre-trained\\nmodel. Since the chat model was pretrained with this prompt template, if you want to run\\ninference on the model, you'll need to use the same template for optimal performance\\non chat data. Otherwise, the model will just perform standard text completion, which\\nmay or may not align with your intended use case.\\n\\nFrom the `official Llama2 prompt\\ntemplate guide `_\\nfor the Llama2 chat model, we can see that special tags are added:\\n\\n.. code-block:: text\\n\\n [INST] <>\\n You are a helpful, respectful, and honest assistant.\\n <>\\n\\n Hi! I am a human. [/INST] Hello there! Nice to meet you! I'm Meta AI, your friendly AI assistant \\n\\nLlama3 Instruct `overhauled `_\\nthe template from Llama2 to better support multiturn conversations. The same text\\nin the Llama3 Instruct format would look like this:\\n\\n.. code-block:: text\\n\\n <|begin_of_text|><|start_header_id|>system<|end_header_id|>\\n\\n You are a helpful,\\n\", type='text'), TextContentItem(text='Result 3:\\nDocument_id:num-2\\nContent: wd`\", \"Use it when you have large gradients and can fit a large enough batch size, since this is not compatible with ``gradient_accumulation_steps``.\"\\n \":ref:`glossary_cpu_offload`\", \"Offloads optimizer states and (optionally) gradients to CPU, and performs optimizer steps on CPU. This can be used to significantly reduce GPU memory usage at the cost of CPU RAM and training speed. Prioritize using it only if the other techniques are not enough.\"\\n \":ref:`glossary_lora`\", \"When you want to significantly reduce the number of trainable parameters, saving gradient and optimizer memory during training, and significantly speeding up training. This may reduce training accuracy\"\\n \":ref:`glossary_qlora`\", \"When you are training a large model, since quantization will save 1.5 bytes * (# of model parameters), at the potential cost of some training speed and accuracy.\"\\n \":ref:`glossary_dora`\", \"a variant of LoRA that may improve model performance at the cost of slightly more memory.\"\\n\\n\\n.. note::\\n\\n In its current state, this tutorial is focused on single-device optimizations. Check in soon as we update this page\\n for the latest memory optimization features for distributed fine-tuning.\\n\\n.. _glossary_precision:\\n\\n\\nModel Precision\\n---------------\\n\\n*What\\'s going on here?*\\n\\nWe use the term \"precision\" to refer to the underlying data type used to represent the model and optimizer parameters.\\nWe support two data types in torchtune:\\n\\n.. note::\\n\\n We recommend diving into Sebastian Raschka\\'s `blogpost on mixed-precision techniques `_\\n for a deeper understanding of concepts around precision and data formats.\\n\\n* ``fp32``, commonly referred to as \"full-precision\", uses 4 bytes per model and optimizer parameter.\\n* ``bfloat16``, referred to as \"half-precision\", uses 2 bytes per model and optimizer parameter - effectively half\\n the memory of ``fp32``, and also improves training speed. Generally, if your hardware supports training with ``bfloat16``,\\n we recommend using it - this is the default setting for our recipes.\\n\\n.. note::\\n\\n Another common paradigm is \"mixed-precision\" training: where model weights are in ``bfloat16`` (or ``fp16``), and optimizer\\n states are in ``fp32``. Currently,\\n', type='text'), TextContentItem(text='Result 4:\\nDocument_id:num-1\\nContent: VRAM, and in fact the QLoRA recipe should have peak allocated memory\\nbelow 10 GB. You can also experiment with different configurations of LoRA and QLoRA, or even run a full fine-tune.\\nTry it out!\\n\\n|\\n\\nEvaluating fine-tuned Llama3-8B models with EleutherAI\\'s Eval Harness\\n---------------------------------------------------------------------\\n\\nNow that we\\'ve fine-tuned our model, what\\'s next? Let\\'s take our LoRA-finetuned model from the\\npreceding section and look at a couple different ways we can evaluate its performance on the tasks we care about.\\n\\nFirst, torchtune provides an integration with\\n`EleutherAI\\'s evaluation harness `_\\nfor model evaluation on common benchmark tasks.\\n\\n.. note::\\n Make sure you\\'ve first installed the evaluation harness via :code:`pip install \"lm_eval==0.4.*\"`.\\n\\nFor this tutorial we\\'ll use the `truthfulqa_mc2 `_ task from the harness.\\nThis task measures a model\\'s propensity to be truthful when answering questions and\\nmeasures the model\\'s zero-shot accuracy on a question followed by one or more true\\nresponses and one or more false responses. First, let\\'s copy the config so we can point the YAML\\nfile to our fine-tuned checkpoint files.\\n\\n.. code-block:: bash\\n\\n tune cp eleuther_evaluation ./custom_eval_config.yaml\\n\\nNext, we modify ``custom_eval_config.yaml`` to include the fine-tuned checkpoints.\\n\\n.. code-block:: yaml\\n\\n model:\\n _component_: torchtune.models.llama3.llama3_8b\\n\\n checkpointer:\\n _component_: torchtune.training.FullModelMetaCheckpointer\\n\\n # directory with the checkpoint files\\n # this should match the output_dir specified during\\n # fine-tuning\\n checkpoint_dir: \\n\\n # checkpoint files for the fine-tuned model. These will be logged\\n # at the end of your fine-tune\\n checkpoint_files: [\\n meta_model_0.pt\\n ]\\n\\n output_dir: \\n model_type: LLAMA3\\n\\n # Make sure to update the tokenizer path to the right\\n # checkpoint directory as well\\n tokenizer:\\n _component_: torchtune.models.llama3.llama3_tokenizer\\n path: /tokenizer.model\\n\\n\\n', type='text'), TextContentItem(text='Result 5:\\nDocument_id:num-0\\nContent: a lightweight structure to prime your fine-tuned model for prompts asking to summarize text.\\nThis would wrap around the user message, with the assistant message untouched.\\n\\n.. code-block:: python\\n\\n f\"Summarize this dialogue:\\\\n{dialogue}\\\\n---\\\\nSummary:\\\\n\"\\n\\nYou can fine-tune Llama2 with this template even though the model was originally pre-trained\\nwith the :class:`~torchtune.models.llama2.Llama2ChatTemplate`, as long as this is what the model\\nsees during inference. The model should be robust enough to adapt to a new template.\\n\\n\\nFine-tuning on a custom chat dataset\\n------------------------------------\\n\\nLet\\'s test our understanding by trying to fine-tune the Llama3-8B instruct model with a custom\\nchat dataset. We\\'ll walk through how to set up our data so that it can be tokenized\\ncorrectly and fed into our model.\\n\\nLet\\'s say we have a local dataset saved as a JSON file that contains conversations\\nwith an AI model. How can we get something like this into a format\\nLlama3 understands and tokenizes correctly?\\n\\n.. code-block:: python\\n\\n # data/my_data.json\\n [\\n {\\n \"dialogue\": [\\n {\\n \"from\": \"human\",\\n \"value\": \"What is your name?\"\\n },\\n {\\n \"from\": \"gpt\",\\n \"value\": \"I am an AI assistant, I don\\'t have a name.\"\\n },\\n {\\n \"from\": \"human\",\\n \"value\": \"Pretend you have a name.\"\\n },\\n {\\n \"from\": \"gpt\",\\n \"value\": \"My name is Mark Zuckerberg.\"\\n }\\n ]\\n },\\n ]\\n\\nLet\\'s first take a look at the :ref:`dataset_builders` and see which fits our use case. Since we\\nhave conversational data, :func:`~torchtune.datasets.chat_dataset` seems to be a good fit. For any\\ncustom local dataset we always need to specify ``source``, ``data_files``, and ``split`` for any dataset\\nbuilder in torchtune. For :func:`~torchtune.datasets.chat_dataset`, we additionally need to specify\\n``conversation_column`` and ``conversation_style``. Our data follows the ``\"sharegpt\"`` format, so\\nwe can specify that here. Altogether, our :func:`~torchtune.datasets.chat_dataset` call should\\nlook like so:\\n\\n.. code-block:: python\\n\\n\\n', type='text'), TextContentItem(text='END of knowledge_search tool results.\\n', type='text')]\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m*\u001b[0m\u001b[33m Fine\u001b[0m\u001b[33m-T\u001b[0m\u001b[33muning\u001b[0m\u001b[33m L\u001b[0m\u001b[33mlama\u001b[0m\u001b[33m3\u001b[0m\u001b[33m with\u001b[0m\u001b[33m Chat\u001b[0m\u001b[33m Data\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33m*\u001b[0m\u001b[33m Model\u001b[0m\u001b[33m Precision\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33m*\u001b[0m\u001b[33m Evalu\u001b[0m\u001b[33mating\u001b[0m\u001b[33m fine\u001b[0m\u001b[33m-t\u001b[0m\u001b[33muned\u001b[0m\u001b[33m L\u001b[0m\u001b[33mlama\u001b[0m\u001b[33m3\u001b[0m\u001b[33m-\u001b[0m\u001b[33m8\u001b[0m\u001b[33mB\u001b[0m\u001b[33m models\u001b[0m\u001b[33m with\u001b[0m\u001b[33m Ele\u001b[0m\u001b[33muther\u001b[0m\u001b[33mAI\u001b[0m\u001b[33m's\u001b[0m\u001b[33m Eval\u001b[0m\u001b[33m Harness\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33m*\u001b[0m\u001b[33m Fine\u001b[0m\u001b[33m-t\u001b[0m\u001b[33muning\u001b[0m\u001b[33m on\u001b[0m\u001b[33m a\u001b[0m\u001b[33m custom\u001b[0m\u001b[33m chat\u001b[0m\u001b[33m dataset\u001b[0m\u001b[33m\n", - "\u001b[0m\u001b[33m*\u001b[0m\u001b[33m Token\u001b[0m\u001b[33mizing\u001b[0m\u001b[33m prompt\u001b[0m\u001b[33m templates\u001b[0m\u001b[33m &\u001b[0m\u001b[33m special\u001b[0m\u001b[33m tokens\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m" + "\u001b[36mCreated vector store: vs_dacf0824-6c3d-4751-82b9-6041bc9db4da\u001b[0m\n" ] } ], @@ -1338,39 +2007,81 @@ "import uuid\n", "from llama_stack_client import Agent, AgentEventLogger, RAGDocument\n", "from termcolor import cprint\n", + "import requests\n", "\n", "urls = [\"chat.rst\", \"llama3.rst\", \"memory_optimizations.rst\", \"lora_finetune.rst\"]\n", - "documents = [\n", - " RAGDocument(\n", - " document_id=f\"num-{i}\",\n", - " content=f\"https://raw.githubusercontent.com/pytorch/torchtune/main/docs/source/tutorials/{url}\",\n", - " mime_type=\"text/plain\",\n", - " metadata={},\n", - " )\n", - " for i, url in enumerate(urls)\n", - "]\n", "\n", - "vector_db_id = f\"test-vector-db-{uuid.uuid4().hex}\"\n", - "client.vector_dbs.register(\n", - " vector_db_id=vector_db_id,\n", - " embedding_model=\"nomic-embed-text-v1.5\",\n", - " embedding_dimension=768,\n", - ")\n", - "client.tool_runtime.rag_tool.insert(\n", - " documents=documents,\n", - " vector_db_id=vector_db_id,\n", - " chunk_size_in_tokens=512,\n", + "# Step 1: Upload files\n", + "file_ids = []\n", + "for i, url in enumerate(urls):\n", + " full_url = f\"https://raw.githubusercontent.com/pytorch/torchtune/main/docs/source/tutorials/{url}\"\n", + " response = requests.get(full_url)\n", + " \n", + " file = client.files.create(\n", + " file=response.content,\n", + " purpose='assistants'\n", + " )\n", + " file_ids.append(file.id)\n", + " \n", + "\n", + "# Step 2: Create a vector store with files\n", + "vector_store = client.vector_stores.create(\n", + " name=f\"torchtune-docs-{uuid.uuid4().hex[:8]}\",\n", + " file_ids=file_ids,\n", + " chunking_strategy={\n", + " \"type\": \"static\",\n", + " \"static\": {\n", + " \"max_chunk_size_tokens\": 512,\n", + " \"chunk_overlap_tokens\": 50\n", + " }\n", + " }\n", ")\n", + "\n", + "cprint(f\"Created vector store: {vector_store.id}\", \"cyan\")" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "3ebacfcb", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/conversations \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/responses \"HTTP/1.1 200 OK\"\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32mUser> What are the top 5 topics that were explained? Only list succinct bullet points.\u001b[0m\n", + "🤔 \n", + "\n", + "🔧 Executing file_search (server-side)...\n", + "🤔 Here are the top 5 topics explained:\n", + "\n", + "* LoRA (Low-Rank Adaptation) and its application in fine-tuning large language models\n", + "* QLoRA (Quantized Low-Rank Adaptation) and its benefits in reducing memory usage\n", + "* Activation checkpointing and its trade-offs between memory and compute\n", + "* Model precision and its impact on memory usage and training speed\n", + "* Prompt templates and special tokens in Llama2 and Llama3 models\n" + ] + } + ], + "source": [ + "# Ask the agent a question related to the uploaded files\n", "rag_agent = Agent(\n", " client,\n", " model=model_id,\n", " instructions=\"You are a helpful assistant\",\n", " tools = [\n", " {\n", - " \"name\": \"builtin::rag/knowledge_search\",\n", - " \"args\" : {\n", - " \"vector_db_ids\": [vector_db_id],\n", - " }\n", + " \"type\": \"file_search\",\n", + " \"vector_store_ids\": [vector_store.id],\n", " }\n", " ],\n", ")\n", @@ -1385,7 +2096,7 @@ " session_id=session_id,\n", " )\n", " for log in AgentEventLogger().log(response):\n", - " log.print()" + " print(log, end=\"\", flush=True)" ] }, { @@ -1395,7 +2106,7 @@ "id": "jSfjNN9fMxtm" }, "source": [ - "### 2.4. Using Model Context Protocol\n", + "### 2.3. Using Model Context Protocol\n", "\n", "In this example, we will show how tools hosted in an MCP server can be configured to be used by the model.\n", "\n", @@ -1406,7 +2117,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 69, "id": "67fDKVVpNuFb", "metadata": { "colab": { @@ -1420,15 +2131,28 @@ "name": "stdout", "output_type": "stream", "text": [ - "Requirement already satisfied: colab-xterm in /opt/homebrew/Caskroom/miniconda/base/envs/stack/lib/python3.10/site-packages (0.2.0)\n", - "Requirement already satisfied: ptyprocess~=0.7.0 in /opt/homebrew/Caskroom/miniconda/base/envs/stack/lib/python3.10/site-packages (from colab-xterm) (0.7.0)\n", - "Requirement already satisfied: tornado>5.1 in /opt/homebrew/Caskroom/miniconda/base/envs/stack/lib/python3.10/site-packages (from colab-xterm) (6.4.2)\n" + "\u001b[2mUsing Python 3.12.11 environment at: /Users/erichuang/projects/lst3/.venv\u001b[0m\n", + "\u001b[2K\u001b[2mResolved \u001b[1m3 packages\u001b[0m \u001b[2min 381ms\u001b[0m\u001b[0m \u001b[0m\n", + "\u001b[2K\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/1) \n", + "\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/1)--------------\u001b[0m\u001b[0m 0 B/112.88 KiB \u001b[1A\n", + "\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/1)--------------\u001b[0m\u001b[0m 16.00 KiB/112.88 KiB \u001b[1A\n", + "\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/1)--------------\u001b[0m\u001b[0m 32.00 KiB/112.88 KiB \u001b[1A\n", + "\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/1)--------------\u001b[0m\u001b[0m 48.00 KiB/112.88 KiB \u001b[1A\n", + "\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/1)2m------------\u001b[0m\u001b[0m 64.00 KiB/112.88 KiB \u001b[1A\n", + "\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/1)--\u001b[2m--------\u001b[0m\u001b[0m 80.00 KiB/112.88 KiB \u001b[1A\n", + "\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/1)------\u001b[2m----\u001b[0m\u001b[0m 96.00 KiB/112.88 KiB \u001b[1A\n", + "\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/1)----------\u001b[2m\u001b[0m\u001b[0m 112.00 KiB/112.88 KiB \u001b[1A\n", + "\u001b[2K\u001b[1A\u001b[37m⠙\u001b[0m \u001b[2mPreparing packages...\u001b[0m (0/1)----------\u001b[2m\u001b[0m\u001b[0m 112.88 KiB/112.88 KiB \u001b[1A\n", + "\u001b[2K\u001b[2mPrepared \u001b[1m1 package\u001b[0m \u001b[2min 45ms\u001b[0m\u001b[0m \u001b[1A\n", + "\u001b[2K\u001b[2mInstalled \u001b[1m1 package\u001b[0m \u001b[2min 16ms\u001b[0m\u001b[0m \u001b[0m\n", + " \u001b[32m+\u001b[39m \u001b[1mcolab-xterm\u001b[0m\u001b[2m==0.2.0\u001b[0m\n" ] } ], "source": [ "# NBVAL_SKIP\n", - "!pip install colab-xterm #https://pypi.org/project/colab-xterm/\n", + "## If running on Colab:\n", + "!uv pip install colab-xterm #https://pypi.org/project/colab-xterm/\n", "%load_ext colabxterm" ] }, @@ -1782,14 +2506,64 @@ "id": "giIA2M-ANUIM", "outputId": "612c3487-1fd7-41ab-f65a-690b1325f46d" }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "Launching Xterm..." + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "🚀 Listen to 10001\n", + "{\"success\": true, \"reason\": null}\n", + "\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "# NBVAL_SKIP\n", + "## If running on Colab:\n", + "\n", "%xterm\n", - "# touch /content/foo\n", - "# echo hello > /content/foo\n", - "# touch /content/bar\n", - "# npx -y supergateway --port 8000 --stdio 'npx -y @modelcontextprotocol/server-filesystem /content'" + "% mkdir /tmp/content\n", + "\n", + "# To be run in the terminal:\n", + "# touch /tmp/content/foo\n", + "# echo hello > /tmp/content/foo\n", + "# touch /tmp/content/bar\n", + "# npx -y supergateway --port 8000 --stdio 'npx -y @modelcontextprotocol/server-filesystem /tmp/content'" ] }, { @@ -1804,352 +2578,7 @@ }, { "cell_type": "code", - "execution_count": 18, - "id": "DwdKhQb1N295", - "metadata": { - "id": "DwdKhQb1N295" - }, - "outputs": [], - "source": [ - "# NBVAL_SKIP\n", - "from llama_stack_client.types.toolgroup_register_params import McpEndpoint\n", - "client.toolgroups.register(\n", - " toolgroup_id=\"mcp::filesystem\",\n", - " provider_id=\"model-context-protocol\",\n", - " mcp_endpoint=McpEndpoint(uri=\"http://localhost:8000/sse\"),\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "ZZ5_vIkDOyAN", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "id": "ZZ5_vIkDOyAN", - "outputId": "f6fa8639-c2d8-497d-f4ed-716b3bf775d4" - }, - "outputs": [ - { - "data": { - "text/html": [ - "
[\n",
-       "Tool(\n",
-       "│   │   description='Read the complete contents of a file from the file system. Handles various text encodings and provides detailed error messages if the file cannot be read. Use this tool when you need to examine the contents of a single file. Only works within allowed directories.',\n",
-       "│   │   identifier='read_file',\n",
-       "│   │   parameters=[Parameter(description='', name='path', parameter_type='string', required=True, default=None)],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='read_file',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       "),\n",
-       "Tool(\n",
-       "│   │   description=\"Read the contents of multiple files simultaneously. This is more efficient than reading files one by one when you need to analyze or compare multiple files. Each file's content is returned with its path as a reference. Failed reads for individual files won't stop the entire operation. Only works within allowed directories.\",\n",
-       "│   │   identifier='read_multiple_files',\n",
-       "│   │   parameters=[Parameter(description='', name='paths', parameter_type='array', required=True, default=None)],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='read_multiple_files',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       "),\n",
-       "Tool(\n",
-       "│   │   description='Create a new file or completely overwrite an existing file with new content. Use with caution as it will overwrite existing files without warning. Handles text content with proper encoding. Only works within allowed directories.',\n",
-       "│   │   identifier='write_file',\n",
-       "│   │   parameters=[\n",
-       "│   │   │   Parameter(description='', name='path', parameter_type='string', required=True, default=None),\n",
-       "│   │   │   Parameter(description='', name='content', parameter_type='string', required=True, default=None)\n",
-       "│   │   ],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='write_file',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       "),\n",
-       "Tool(\n",
-       "│   │   description='Make line-based edits to a text file. Each edit replaces exact line sequences with new content. Returns a git-style diff showing the changes made. Only works within allowed directories.',\n",
-       "│   │   identifier='edit_file',\n",
-       "│   │   parameters=[\n",
-       "│   │   │   Parameter(description='', name='path', parameter_type='string', required=True, default=None),\n",
-       "│   │   │   Parameter(description='', name='edits', parameter_type='array', required=True, default=None),\n",
-       "│   │   │   Parameter(\n",
-       "│   │   │   │   description='Preview changes using git-style diff format',\n",
-       "│   │   │   │   name='dryRun',\n",
-       "│   │   │   │   parameter_type='boolean',\n",
-       "│   │   │   │   required=True,\n",
-       "│   │   │   │   default=None\n",
-       "│   │   │   )\n",
-       "│   │   ],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='edit_file',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       "),\n",
-       "Tool(\n",
-       "│   │   description='Create a new directory or ensure a directory exists. Can create multiple nested directories in one operation. If the directory already exists, this operation will succeed silently. Perfect for setting up directory structures for projects or ensuring required paths exist. Only works within allowed directories.',\n",
-       "│   │   identifier='create_directory',\n",
-       "│   │   parameters=[Parameter(description='', name='path', parameter_type='string', required=True, default=None)],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='create_directory',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       "),\n",
-       "Tool(\n",
-       "│   │   description='Get a detailed listing of all files and directories in a specified path. Results clearly distinguish between files and directories with [FILE] and [DIR] prefixes. This tool is essential for understanding directory structure and finding specific files within a directory. Only works within allowed directories.',\n",
-       "│   │   identifier='list_directory',\n",
-       "│   │   parameters=[Parameter(description='', name='path', parameter_type='string', required=True, default=None)],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='list_directory',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       "),\n",
-       "Tool(\n",
-       "│   │   description=\"Get a recursive tree view of files and directories as a JSON structure. Each entry includes 'name', 'type' (file/directory), and 'children' for directories. Files have no children array, while directories always have a children array (which may be empty). The output is formatted with 2-space indentation for readability. Only works within allowed directories.\",\n",
-       "│   │   identifier='directory_tree',\n",
-       "│   │   parameters=[Parameter(description='', name='path', parameter_type='string', required=True, default=None)],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='directory_tree',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       "),\n",
-       "Tool(\n",
-       "│   │   description='Move or rename files and directories. Can move files between directories and rename them in a single operation. If the destination exists, the operation will fail. Works across different directories and can be used for simple renaming within the same directory. Both source and destination must be within allowed directories.',\n",
-       "│   │   identifier='move_file',\n",
-       "│   │   parameters=[\n",
-       "│   │   │   Parameter(description='', name='source', parameter_type='string', required=True, default=None),\n",
-       "│   │   │   Parameter(description='', name='destination', parameter_type='string', required=True, default=None)\n",
-       "│   │   ],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='move_file',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       "),\n",
-       "Tool(\n",
-       "│   │   description=\"Recursively search for files and directories matching a pattern. Searches through all subdirectories from the starting path. The search is case-insensitive and matches partial names. Returns full paths to all matching items. Great for finding files when you don't know their exact location. Only searches within allowed directories.\",\n",
-       "│   │   identifier='search_files',\n",
-       "│   │   parameters=[\n",
-       "│   │   │   Parameter(description='', name='path', parameter_type='string', required=True, default=None),\n",
-       "│   │   │   Parameter(description='', name='pattern', parameter_type='string', required=True, default=None),\n",
-       "│   │   │   Parameter(\n",
-       "│   │   │   │   description='',\n",
-       "│   │   │   │   name='excludePatterns',\n",
-       "│   │   │   │   parameter_type='array',\n",
-       "│   │   │   │   required=True,\n",
-       "│   │   │   │   default=None\n",
-       "│   │   │   )\n",
-       "│   │   ],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='search_files',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       "),\n",
-       "Tool(\n",
-       "│   │   description='Retrieve detailed metadata about a file or directory. Returns comprehensive information including size, creation time, last modified time, permissions, and type. This tool is perfect for understanding file characteristics without reading the actual content. Only works within allowed directories.',\n",
-       "│   │   identifier='get_file_info',\n",
-       "│   │   parameters=[Parameter(description='', name='path', parameter_type='string', required=True, default=None)],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='get_file_info',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       "),\n",
-       "Tool(\n",
-       "│   │   description='Returns the list of directories that this server is allowed to access. Use this to understand which directories are available before trying to access files.',\n",
-       "│   │   identifier='list_allowed_directories',\n",
-       "│   │   parameters=[],\n",
-       "│   │   provider_id='model-context-protocol',\n",
-       "│   │   provider_resource_id='list_allowed_directories',\n",
-       "│   │   tool_host='model_context_protocol',\n",
-       "│   │   toolgroup_id='mcp::filesystem',\n",
-       "│   │   type='tool',\n",
-       "│   │   metadata={'endpoint': 'http://localhost:8000/sse'}\n",
-       ")\n",
-       "]\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m'Read the complete contents of a file from the file system. Handles various text encodings and provides detailed error messages if the file cannot be read. Use this tool when you need to examine the contents of a single file. Only works within allowed directories.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'read_file'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'path'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'read_file'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m\"Read\u001b[0m\u001b[32m the contents of multiple files simultaneously. This is more efficient than reading files one by one when you need to analyze or compare multiple files. Each file's content is returned with its path as a reference. Failed reads for individual files won't stop the entire operation. Only works within allowed directories.\"\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'read_multiple_files'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'paths'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'array'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'read_multiple_files'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m'Create a new file or completely overwrite an existing file with new content. Use with caution as it will overwrite existing files without warning. Handles text content with proper encoding. Only works within allowed directories.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'write_file'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'path'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'content'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'write_file'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m'Make line-based edits to a text file. Each edit replaces exact line sequences with new content. Returns a git-style diff showing the changes made. Only works within allowed directories.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'edit_file'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'path'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'edits'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'array'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m'Preview changes using git-style diff format'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mname\u001b[0m=\u001b[32m'dryRun'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mparameter_type\u001b[0m=\u001b[32m'boolean'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'edit_file'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m'Create a new directory or ensure a directory exists. Can create multiple nested directories in one operation. If the directory already exists, this operation will succeed silently. Perfect for setting up directory structures for projects or ensuring required paths exist. Only works within allowed directories.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'create_directory'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'path'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'create_directory'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m'Get a detailed listing of all files and directories in a specified path. Results clearly distinguish between files and directories with \u001b[0m\u001b[32m[\u001b[0m\u001b[32mFILE\u001b[0m\u001b[32m]\u001b[0m\u001b[32m and \u001b[0m\u001b[32m[\u001b[0m\u001b[32mDIR\u001b[0m\u001b[32m]\u001b[0m\u001b[32m prefixes. This tool is essential for understanding directory structure and finding specific files within a directory. Only works within allowed directories.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'list_directory'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'path'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'list_directory'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m\"Get\u001b[0m\u001b[32m a recursive tree view of files and directories as a JSON structure. Each entry includes 'name', 'type' \u001b[0m\u001b[32m(\u001b[0m\u001b[32mfile/directory\u001b[0m\u001b[32m)\u001b[0m\u001b[32m, and 'children' for directories. Files have no children array, while directories always have a children array \u001b[0m\u001b[32m(\u001b[0m\u001b[32mwhich may be empty\u001b[0m\u001b[32m)\u001b[0m\u001b[32m. The output is formatted with 2-space indentation for readability. Only works within allowed directories.\"\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'directory_tree'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'path'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'directory_tree'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m'Move or rename files and directories. Can move files between directories and rename them in a single operation. If the destination exists, the operation will fail. Works across different directories and can be used for simple renaming within the same directory. Both source and destination must be within allowed directories.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'move_file'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'source'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'destination'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'move_file'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m\"Recursively\u001b[0m\u001b[32m search for files and directories matching a pattern. Searches through all subdirectories from the starting path. The search is case-insensitive and matches partial names. Returns full paths to all matching items. Great for finding files when you don't know their exact location. Only searches within allowed directories.\"\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'search_files'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'path'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'pattern'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mname\u001b[0m=\u001b[32m'excludePatterns'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mparameter_type\u001b[0m=\u001b[32m'array'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'search_files'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m'Retrieve detailed metadata about a file or directory. Returns comprehensive information including size, creation time, last modified time, permissions, and type. This tool is perfect for understanding file characteristics without reading the actual content. Only works within allowed directories.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'get_file_info'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\u001b[1;35mParameter\u001b[0m\u001b[1m(\u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m''\u001b[0m, \u001b[33mname\u001b[0m=\u001b[32m'path'\u001b[0m, \u001b[33mparameter_type\u001b[0m=\u001b[32m'string'\u001b[0m, \u001b[33mrequired\u001b[0m=\u001b[3;92mTrue\u001b[0m, \u001b[33mdefault\u001b[0m=\u001b[3;35mNone\u001b[0m\u001b[1m)\u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'get_file_info'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1;35mTool\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mdescription\u001b[0m=\u001b[32m'Returns the list of directories that this server is allowed to access. Use this to understand which directories are available before trying to access files.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33midentifier\u001b[0m=\u001b[32m'list_allowed_directories'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mparameters\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m]\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_id\u001b[0m=\u001b[32m'model-context-protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mprovider_resource_id\u001b[0m=\u001b[32m'list_allowed_directories'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtool_host\u001b[0m=\u001b[32m'model_context_protocol'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtoolgroup_id\u001b[0m=\u001b[32m'mcp::filesystem'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mtype\u001b[0m=\u001b[32m'tool'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[33mmetadata\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'endpoint'\u001b[0m: \u001b[32m'http://localhost:8000/sse'\u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[1m]\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "pprint(client.tools.list(toolgroup_id=\"mcp::filesystem\"))" - ] - }, - { - "cell_type": "code", - "execution_count": null, + "execution_count": 53, "id": "vttLbj_YO01f", "metadata": { "colab": { @@ -2159,50 +2588,44 @@ "outputId": "04bc486c-3a61-49c6-d0d2-4a211d6de0b5" }, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/conversations \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/responses \"HTTP/1.1 200 OK\"\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[32mUser> Hello\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[list\u001b[0m\u001b[33m_allowed\u001b[0m\u001b[33m_direct\u001b[0m\u001b[33mories\u001b[0m\u001b[33m()]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:list_allowed_directories Args:{}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:list_allowed_directories Response:{\"type\":\"text\",\"text\":\"Allowed directories:\\n/tmp/content\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[list\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:list_directory Args:{'path': '/tmp/content'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:list_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp/content'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m\"),\u001b[0m\u001b[33m create\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Access denied - path outside allowed directories: /tmp not in /tmp/content\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[list\u001b[0m\u001b[33m_allowed\u001b[0m\u001b[33m_direct\u001b[0m\u001b[33mories\u001b[0m\u001b[33m()]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:list_allowed_directories Args:{}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:list_allowed_directories Response:{\"type\":\"text\",\"text\":\"Allowed directories:\\n/tmp/content\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m/sub\u001b[0m\u001b[33mdir\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp/content/subdir'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp/content\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp/content'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[list\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:list_directory Args:{'path': '/tmp/content'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:list_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp/content'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[list\u001b[0m\u001b[33m_allowed\u001b[0m\u001b[33m_direct\u001b[0m\u001b[33mories\u001b[0m\u001b[33m()]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[32mUser> Whats written in /tmp/content/foo ?\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mread\u001b[0m\u001b[33m_file\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m/foo\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:read_file Args:{'path': '/tmp/content/foo'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:read_file Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp/content\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mcreate\u001b[0m\u001b[33m_directory\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Args:{'path': '/tmp/content'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:create_directory Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33m[\u001b[0m\u001b[33mwrite\u001b[0m\u001b[33m_file\u001b[0m\u001b[33m(path\u001b[0m\u001b[33m=\"/\u001b[0m\u001b[33mtmp\u001b[0m\u001b[33m/content\u001b[0m\u001b[33m/foo\u001b[0m\u001b[33m\",\u001b[0m\u001b[33m content\u001b[0m\u001b[33m=\"\u001b[0m\u001b[33mHello\u001b[0m\u001b[33m World\u001b[0m\u001b[33m!\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:write_file Args:{'path': '/tmp/content/foo', 'content': 'Hello World!'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:write_file Response:{\"type\":\"text\",\"text\":\"Error: Parent directory does not exist: /tmp/content\",\"annotations\":null}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[31m500: Internal server error: An unexpected error occurred.\u001b[0m\n" + "🤔 \n", + "\n", + "🔧 Executing mcp_list_tools (server-side)...\n", + "🤔 Hi there! How can I assist you today?\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/responses \"HTTP/1.1 200 OK\"\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[32mUser> Whats written in /private/tmp/content/foo ?\u001b[0m\n", + "🤔 \n", + "\n", + "🔧 Executing mcp_list_tools (server-side)...\n", + "🤔 \n", + "\n", + "🔧 Executing mcp_call (server-side)...\n", + "🤔 The file located at `/private/tmp/content/foo` contains the text \"hi\".\n" ] } ], @@ -2215,11 +2638,15 @@ " client,\n", " model=model_id,\n", " instructions=\"You are a helpful assistant\",\n", - " tools=[\"mcp::filesystem\"],\n", + " tools=[{\n", + " \"type\": \"mcp\",\n", + " \"server_label\": \"filesystem\",\n", + " \"server_url\": \"http://localhost:8000/sse\",\n", + " }],\n", ")\n", "user_prompts = [\n", " \"Hello\",\n", - " \"Whats written in /content/foo ?\",\n", + " \"Whats written in /private/tmp/content/foo ?\",\n", "]\n", "\n", "session_id = agent.create_session(\"test-session\")\n", @@ -2235,590 +2662,7 @@ " session_id=session_id,\n", " )\n", " for log in AgentEventLogger().log(response):\n", - " log.print()\n" - ] - }, - { - "cell_type": "markdown", - "id": "FJ85DUhgBZd7", - "metadata": { - "id": "FJ85DUhgBZd7" - }, - "source": [ - "## 3. Llama Stack Agent Evaluations\n" - ] - }, - { - "cell_type": "markdown", - "id": "ydeBDpDT5VHd", - "metadata": { - "id": "ydeBDpDT5VHd" - }, - "source": [ - "#### 3.1. Online Evaluation Dataset Collection\n", - "\n", - "- Llama Stack allows you to query each steps of the agents execution in your application. \n", - "- In this example, we will show how to \n", - " 1. build an Agent with Llama Stack\n", - " 2. Query the agent's session, turns, and steps\n", - " 3. Evaluate the results" - ] - }, - { - "cell_type": "markdown", - "id": "_t_tcWq0JcJ4", - "metadata": { - "id": "_t_tcWq0JcJ4" - }, - "source": [ - "##### 3.1.1. Building a Search Agent\n", - "\n", - "First, let's build an agent that have access to a search tool with Llama Stack, and use it to run some user queries. " - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4iCO59kP20Zs", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "4iCO59kP20Zs", - "outputId": "894c6333-30e9-4f1e-9b63-1bfb1cae51e2" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mN\u001b[0m\u001b[36mBA\u001b[0m\u001b[36m Western\u001b[0m\u001b[36m Conference\u001b[0m\u001b[36m Finals\u001b[0m\u001b[36m \u001b[0m\u001b[36m202\u001b[0m\u001b[36m4\u001b[0m\u001b[36m teams\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Args:{'query': 'NBA Western Conference Finals 2024 teams'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"NBA Western Conference Finals 2024 teams\", \"top_k\": [{\"title\": \"2024 NBA Western Conference Finals - Basketball-Reference.com\", \"url\": \"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\", \"content\": \"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks (4-1) vs. 7 Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\u00a0Reference\\u202f\\u00ae Baseball Football (college) Basketball (college) Hockey F\\u00fatbol Blog Stathead\\u202f\\u00ae Immaculate Grid\\u202f\\u00ae\", \"score\": 0.89030397, \"raw_content\": null}, {\"title\": \"NBA Standings - 2024-25 season - ESPN\", \"url\": \"https://www.espn.com/nba/standings\", \"content\": \"NBA Standings - 2024-25 season - ESPN Skip to main contentSkip to navigation ESPN NFL NBA NCAAF NHL NCAAM NCAAW Soccer More Sports Watch Fantasy NBA Home Scores Schedule Standings Stats Teams Odds Where To Watch All-Star Game Fantasy More NBA Standings 2024-25 Standings Expanded Vs. Division NBA Cup LeagueConferenceDivision Eastern Conference | | | --- | | 1CLECleveland Cavaliers | | 2BOSBoston Celtics | | 3NYNew York Knicks | | 4INDIndiana Pacers | | 5MILMilwaukee Bucks | | 6DETDetroit Pistons | | 7MIAMiami Heat | | 8ORLOrlando Magic | | 9ATLAtlanta Hawks | | 10CHIChicago Bulls | | PHIPhiladelphia 76ers | | BKNBrooklyn Nets | | TORToronto Raptors | | CHACharlotte Hornets | | WSHWashington Wizards | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 42 | 10 | .808 | - | 24-4 | 18-6 | 9-1 | 28-7 | 122.4 | 112.1 | +10.3 | W2 | 6-4 | | 36 | 16 | .692 | 6 | 16-10 | 20-6 | 6-2 | 26-9 | 117.3 | 108.8 | +8.5 | L1 | 7-3 | | 34 | 17 | .667 | 7.5 | 18-9 | 16-8 | 9-1 | 23-10 | 117.9 | 111.4 | +6.5 | W2 | 8-2 | | 29 | 21 | .580 | 12 | 14-7 | 14-13 | 6-4 | 17-15 | 115.7 | 114.9 | +0.8 | W1 | 7-3 | | 27 | 23 | .540 | 14 | 16-8 | 10-15 | 6-5 | 22-16 | 114.2 | 112.6 | +1.6 | L1 | 4-6 | | 26 | 26 | .500 | 16 | 13-13 | 13-13 | 2-9 | 18-20 | 113.0 | 113.8 | -0.8 | W1 | 5-5 | | 25 | 25 | .500 | 16 | 12-10 | 12-15 | 5-3 | 14-15 | 110.5 | 110.6 | -0.1 | L1 | 5-5 | | 25 | 28 | .472 | 17.5 | 15-9 | 10-19 | 5-2 | 20-15 | 103.8 | 105.6 | -1.8 | L1 | 2-8 | | 24 | 28 | .462 | 18 | 12-12 | 12-15 | 4-2 | 17-13 | 116.1 | 119.0 | -2.9 | W1 | 2-8 | | 22 | 30 | .423 | 20 | 10-16 | 12-14 | 3-7 | 17-18 | 116.7 | 120.1 | -3.4 | L1 | 4-6 | | 20 | 31 | .392 | 21.5 | 10-16 | 10-15 | 3-4 | 14-17 | 109.1 | 112.9 | -3.8 | L2 | 5-5 | | 18 | 34 | .346 | 24 | 7-17 | 11-17 | 1-8 | 9-23 | 105.3 | 111.7 | -6.4 | W1 | 4-6 | | 16 | 36 | .308 | 26 | 12-16 | 4-20 | 3-7 | 10-23 | 111.2 | 116.9 | -5.7 | L3 | 6-4 | | 13 | 36 | .265 | 27.5 | 9-20 | 4-16 | 0-9 | 7-27 | 107.1 | 112.3 | -5.2 | W1 | 2-8 | | 9 | 42 | .176 | 32.5 | 5-20 | 4-21 | 5-3 | 7-21 | 107.8 | 121.5 | -13.7 | L1 | 3-7 | Western Conference | | | --- | | 1OKCOklahoma City Thunder | | 2MEMMemphis Grizzlies | | 3DENDenver Nuggets | | 4HOUHouston Rockets | | 5LALLos Angeles Lakers | | 6MINMinnesota Timberwolves | | 7LACLA Clippers | | 8DALDallas Mavericks | | 9PHXPhoenix Suns | | 10SACSacramento Kings | | GSGolden State Warriors | | SASan Antonio Spurs | | PORPortland Trail Blazers | | UTAHUtah Jazz | | NONew Orleans Pelicans | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 41 | 9 | .820 | - | 23-3 | 17-6 | 7-1 | 23-8 | 117.7 | 104.7 | +13.0 | W4 | 7-3 | | 35 | 16 | .686 | 6.5 | 21-5 | 14-11 | 8-4 | 19-12 | 123.8 | 115.4 | +8.4 | W4 | 9-1 | | 33 | 19 | .635 | 9 | 17-8 | 16-11 | 4-4 | 19-12 | 120.8 | 115.9 | +4.9 | W5 | 7-3 | | 32 | 20 | .615 | 10 | 15-8 | 17-11 | 9-3 | 19-12 | 113.3 | 109.1 | +4.2 | L6 | 4-6 | | 30 | 19 | .612 | 10.5 | 17-6 | 13-13 | 9-3 | 19-11 | 112.6 | 112.0 | +0.6 | W4 | 8-2 | | 29 | 23 | .558 | 13 | 14-12 | 15-11 | 4-3 | 21-14 | 111.7 | 108.2 | +3.5 | W2 | 7-3 | | 28 | 23 | .549 | 13.5 | 17-10 | 11-13 | 6-4 | 17-18 | 110.1 | 107.7 | +2.4 | L3 | 4-6 | | 28 | 25 | .528 | 14.5 | 15-10 | 13-15 | 6-4 | 20-17 | 115.5 | 113.3 | +2.2 | W2 | 5-5 | | 26 | 25 | .510 | 15.5 | 16-9 | 10-16 | 7-4 | 17-14 | 113.4 | 114.7 | -1.3 | W1 | 5-5 | | 25 | 26 | .490 | 16.5 | 13-13 | 12-13 | 4-6 | 16-17 | 116.1 | 115.4 | +0.7 | L2 | 4-6 | | 25 | 26 | .490 | 16.5 | 15-13 | 10-13 | 1-10 | 17-18 | 111.5 | 111.9 | -0.4 | L2 | 4-6 | | 22 | 27 | .449 | 18.5 | 13-12 | 8-14 | 2-7 | 16-18 | 112.8 | 114.3 | -1.5 | L1 | 3-7 | | 23 | 29 | .442 | 19 | 15-13 | 8-16 | 4-5 | 14-24 | 109.0 | 113.9 | -4.9 | W6 | 9-1 | | 12 | 38 | .240 | 29 | 5-18 | 7-20 | 1-7 | 4-29 | 111.9 | 118.9 | -7.0 | L1 | 2-8 | | 12 | 39 | .235 | 29.5 | 8-18 | 4-21 | 1-8 | 6-23 | 110.0 | 118.8 | -8.8 | L7 | 3-7 | Standings are updated with the completion of each game.Teams seeded 7-10 in each conference will compete in a play-in tournament at the end of the regular season. Glossary W:Wins L:Losses PCT:Winning Percentage GB:Games Back HOME:Home Record AWAY:Away Record DIV:Division Record CONF:Conference Record PPG:Points Per Game OPP PPG:Opponent Points Per Game DIFF:Average Point Differential STRK:Current Streak L10:Record last 10 games NBA News Anthony Davis leads Mavericks past Rockets 116-105 in Mavs debut but leaves with lower-body injury -------------------------------------------------------------------------------------------------- \\u2014 Anthony Davis had 26 points, 16 rebounds, seven assists and three blocks in his Mavericks debut but left the game late in the third quarter with a... * 38m Hawks request waivers on newly acquired Bones Hyland ---------------------------------------------------- The Atlanta Hawks requested waivers on guard Bones Hyland on Saturday, just two days after the guard was obtained from the Clippers in a deal at the NBA trade deadline. * 1h AD posts 26-point double-double in debut before suffering injury ---------------------------------------------------------------- Anthony Davis has a strong debut with the Mavs, dropping 26 points, 16 rebounds and 7 assists, before leaving with a lower-body injury. * 1h All NBA News Terms of Use Privacy Policy Your US State Privacy Rights Children's Online Privacy Policy Interest-Based Ads About Nielsen Measurement Do Not Sell or Share My Personal Information Contact Us Disney Ad Sales Site Work for ESPN Corrections ESPN BET Sportsbook is owned and operated by PENN Entertainment, Inc. and its subsidiaries ('PENN').\", \"score\": 0.83549726, \"raw_content\": null}, {\"title\": \"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) | NBA.com\", \"url\": \"https://www.nba.com/playoffs/2024/west-final\", \"content\": \"Mavericks (5) | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: 'This is special, coming from the West' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\", \"score\": 0.75312227, \"raw_content\": null}, {\"title\": \"2024 NBA Playoffs | Official Bracket, Schedule and Series Matchups\", \"url\": \"https://www.nba.com/playoffs/2024?os=wtmbloozowcj&ref=app\", \"content\": \"Draft Kings DFS NBA Store NBA Play NBA Finals ### Chasing History: Celtics clinch banner 18 (Ep. 25) Jayson Tatum and Finals MVP Jaylen Brown close out Dallas in Game 5 to secure Boston's NBA-record 18th championship. WE DID ITTTT!' Jayson Tatum walkoff interview after Celtics defeat Mavericks in Game 5 of 2024 NBA Finals, clinching title with a 4-1 series win. ### Horford finally champ after key sacrifice Al Horford, who played the most playoff games in NBA history before winning his 1st title, crosses the plateau in his 17th season. 30:13 ### Best of the 2024 NBA Finals 17:47 ### Best of Boston Celtics from the 2024 NBA Finals\", \"score\": 0.63234437, \"raw_content\": null}, {\"title\": \"2025 NBA Playoffs: Standings, bracket and clinching updates\", \"url\": \"https://www.nba.com/news/2025-nba-playoffs-standings-and-bracket-updates\", \"content\": \"NBA TV NBA Play NBA Store NBA Game Worn NBA Play NBA Official NBA Playoffs bracket ### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. Click \\\"Access Content\\\" to agree to our Terms of Use and Privacy Policy and to sign up for emails about the latest news and products from the NBA Family and its partners. #### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. NBA ID NBA Official NBA Transactions NBA Auctions\", \"score\": 0.13435538, \"raw_content\": null}]}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33mThe\u001b[0m\u001b[33m teams\u001b[0m\u001b[33m that\u001b[0m\u001b[33m played\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m NBA\u001b[0m\u001b[33m Western\u001b[0m\u001b[33m Conference\u001b[0m\u001b[33m Finals\u001b[0m\u001b[33m of\u001b[0m\u001b[33m \u001b[0m\u001b[33m202\u001b[0m\u001b[33m4\u001b[0m\u001b[33m were\u001b[0m\u001b[33m the\u001b[0m\u001b[33m Dallas\u001b[0m\u001b[33m Mavericks\u001b[0m\u001b[33m and\u001b[0m\u001b[33m the\u001b[0m\u001b[33m Minnesota\u001b[0m\u001b[33m Timber\u001b[0m\u001b[33mw\u001b[0m\u001b[33molves\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mSouth\u001b[0m\u001b[36m Park\u001b[0m\u001b[36m Bill\u001b[0m\u001b[36m Cosby\u001b[0m\u001b[36m episode\u001b[0m\u001b[36m season\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Args:{'query': 'South Park Bill Cosby episode season'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"South Park Bill Cosby episode season\", \"top_k\": [{\"title\": \"Bill Cosby | South Park Archives | Fandom\", \"url\": \"https://southpark.fandom.com/wiki/Bill_Cosby\", \"content\": \"SIGN IN CHARACTERS SIGN IN Explore EXPLORE CHARACTERS SIGN IN TO EDIT Character Information For other uses, see Bill (Disambiguation). Bill Cosby is elderly, having gray hair as well as various facial wrinkles. More Information: Criminal Celebrities More Information: Movie Celebrities Minor Characters from Season Four More information: List of Minor Characters from Season Four | Season Four Community content is available under CC-BY-SA unless otherwise noted. EXPLORE PROPERTIES FOLLOW US Terms of Use Global Sitemap Local Sitemap Follow on IG\", \"score\": 0.48294178, \"raw_content\": null}, {\"title\": \"Stunning and Brave - Wikipedia\", \"url\": \"https://en.wikipedia.org/wiki/Stunning_and_Brave\", \"content\": \"South Park episode \\\"Stunning and Brave\\\" is the first episode in the nineteenth season of the American animated television series South Park. Cartman and others mount an 'anti-PC' assault on the fraternity house but Kyle interrupts it, publicly calling Jenner a hero and brave. IGN's Max Nicholson gave the episode a 7.8 out of 10 and stated \\\"South Park's latest episode took on political correctness with scathing wit and truly outrageous moments.\\\"[1] \\\"South Park: \\\"Stunning and Brave\\\" Review\\\". \\\"South Park: Stunning and Brave Review\\\". \\\"South Park: Stunning and Brave\\\". \\\"South Park premiere is 'Stunning and Brave'\\\". \\\"Stunning and Brave\\\" Full episode at South Park Studios South Park episodes\", \"score\": 0.21465065, \"raw_content\": null}, {\"title\": \"Here Comes the Neighborhood - Wikipedia\", \"url\": \"https://en.wikipedia.org/wiki/Here_Comes_the_Neighborhood\", \"content\": \"\\\"Here Comes the Neighborhood\\\" is the 12th episode of the fifth season of the animated television series South Park, and the 77th episode of the series overall. Despondent at his social estrangement, Token decides to arrange for dozens of rich people (who all happen to be black) such as Will Smith and Snoop Dogg to move into South Park, which leads to Mr. Garrison complaining about the \\\"richers\\\" in the town, which in turn leads to ire among the other, less affluent members of the community (who all happen to be white). \\\"Here Comes the Neighborhood,\\\" along with the thirteen other episodes from South Park: the Complete Fifth Season, was released on a three-disc DVD set in the United States on February 22, 2005. South Park: The Complete Fifth Season: \\\"Here Comes the Neighborhood\\\" (DVD Disc audio commentary). \\\"Here Comes the Neighborhood\\\" Full episode at South Park Studios\", \"score\": 0.19947985, \"raw_content\": null}, {\"title\": \"Trapper Keeper | South Park Archives | Fandom\", \"url\": \"https://southpark.fandom.com/wiki/Trapper_Keeper\", \"content\": \"Trapper Keeper | South Park Archives | Fandom Episodes Episodes in: Episodes, Featured Article Winners, Season 4, Episodes Focusing On Cartman | Episode no. Episode 12 | | List of all South Park episodes | \\\"Trapper Keeper\\\" is the twelfth episode of Season Four and the 60th overall episode of South Park. Kyle takes a Dawson's Creek Trapper Keeper with him to school and is soon met by Cartman. Cartman brags about his Dawson's Creek Trapper Keeper Ultra Keeper Futura S 2000, of which shows off many features that far exceed Kyle's. \\u2191 Jump up to: 1.0 1.1 Trapper Keeper (Season 4, Episode 13). Episodes Episodes Focusing On Cartman Espa\\u00f1ol Fran\\u00e7ais Italiano Portugu\\u00eas do Brasil \\u4e2d\\u6587\", \"score\": 0.1287991, \"raw_content\": null}, {\"title\": \"\\\"South Park\\\" Trapper Keeper (TV Episode 2000) - IMDb\", \"url\": \"https://www.imdb.com/title/tt0705978/\", \"content\": \"Trapper Keeper is a very interesting south park episode.It spoofs plenty of classic sci-fi films such as The Terminator, 2001 A Space Odyssea and the 1988 anime classic Akira(great movie if you haven't seen it).The episode has Cartman with a Dawson's Creek Trapper Keeper.A trapper keeper seems to be a school supply(I have never heard of it before).Cartman's trapper keeper is very advanced in terms of technology, however a robot from the future has come to destroy it because the trapper keeper takes over the world and destroys humanity in the future.The Trapper Keeper turns into a big blob(like in Akira) and sucks Cartman in.It then roams South Park and the boys try to stop it.Meanwhile, Kyle's brother Ike starts kindergarten where Garrison is the teacher.They decide to have a vote for class president between Ike and a kid named Filmore.It turns into a heated debate!\", \"score\": 0.12658015, \"raw_content\": null}]}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33mBill\u001b[0m\u001b[33m Cosby\u001b[0m\u001b[33m first\u001b[0m\u001b[33m appears\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m episode\u001b[0m\u001b[33m \"\u001b[0m\u001b[33mTr\u001b[0m\u001b[33mapped\u001b[0m\u001b[33m in\u001b[0m\u001b[33m the\u001b[0m\u001b[33m Closet\u001b[0m\u001b[33m\"\u001b[0m\u001b[33m (\u001b[0m\u001b[33mSeason\u001b[0m\u001b[33m \u001b[0m\u001b[33m9\u001b[0m\u001b[33m,\u001b[0m\u001b[33m Episode\u001b[0m\u001b[33m \u001b[0m\u001b[33m12\u001b[0m\u001b[33m)\u001b[0m\u001b[33m of\u001b[0m\u001b[33m South\u001b[0m\u001b[33m Park\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m\u001b[33minference> \u001b[0m\u001b[36m\u001b[0m\u001b[36mbr\u001b[0m\u001b[36mave\u001b[0m\u001b[36m_search\u001b[0m\u001b[36m.call\u001b[0m\u001b[36m(query\u001b[0m\u001b[36m=\"\u001b[0m\u001b[36mAndrew\u001b[0m\u001b[36m Tate\u001b[0m\u001b[36m kick\u001b[0m\u001b[36mboxing\u001b[0m\u001b[36m name\u001b[0m\u001b[36m\")\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Args:{'query': 'Andrew Tate kickboxing name'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:brave_search Response:{\"query\": \"Andrew Tate kickboxing name\", \"top_k\": [{\"title\": \"Andrew Tate Height, Weight, Biography, Age, Wife ... - News Unzip\", \"url\": \"https://www.newsunzip.com/wiki/andrew-tate/\", \"content\": \"Andrew Tate aka King Cobra (Real Name: 'Emory Andrew Tate III', born 1 December 1986, Age: 36 Years) is a professional kickboxer, MMA fighter, internet. Monday , 10 March 2025 ... Andrew's Kickboxing and MMA Record Andrew Tate Net worth, Lifestyle & Cars Collection. Andrew is a millionaire businessman. He makes a lot of money from his\", \"score\": 0.85995835, \"raw_content\": null}, {\"title\": \"The Life Of Andrew Tate (By Andrew Tate Himself ... - Sidekick Boxing\", \"url\": \"https://sidekickboxing.co.uk/the-life-of-andrew-king-cobra-tate/\", \"content\": \"Andrew Tate is a British-American former professional kickboxing world champion who fought in the cruiserweight and super cruiserweight divisions. Andrew Tate\\u2019s Kickboxing Career Andrew Tate in the Big Brother house Andrew Tate\\u2019s Kickboxing World Titles and his Sidekick boxing gloves Andrew Tate After Kickboxing Andrew Tate and his brother Tristan moved to Romania to set up their empire of businesses including trading in Bitcoin, Hustlers University, CobraTate.com, The Real World, and The War Room. From being a 4x kickboxing world champion to becoming the world\\u2019s most Googled man in the world with a private jet and over 33 cars, Andrew Tate\\u2019s life has been full of adventure.\", \"score\": 0.78194773, \"raw_content\": null}, {\"title\": \"Andrew Tate (\\\"King Cobra\\\") | MMA Fighter Page - Tapology\", \"url\": \"https://www.tapology.com/fightcenter/fighters/72139-andrew-tate\", \"content\": \"Andrew Tate (\\\"King Cobra\\\") | MMA Fighter Page | Tapology Andrew \\\"King Cobra\\\" Tate Andrew Tate Name: Andrew Tate Height: 6'1\\\" (185cm) | Reach: Andrew Tate is ineligible for Tapology's regional MMA rankings due to inactivity. Fighters must have at least one completed MMA bout in the past two years to be ranked. Andrew Tate MMA Fight Record Former top-ranked UFC fighter has called out Andrew Tate for having a paper title when it comes to combat... Andrew Tate \\u2022 All the biggest upcoming MMA & Boxing fights | UFC Fight Night | 02.01.2025, 12:00 PM ET | MMA Junkie: UFC Fight Night 249 video: Nine stoppages to open the year?! MMA Mania: Prochazka Vs. Hill: Odds, Full Fight Preview & Prediction\", \"score\": 0.6999322, \"raw_content\": null}, {\"title\": \"Andrew Tate: Kickboxing Record, Facts, Height, Weight, Age, Biography\", \"url\": \"https://www.lowkickmma.com/andrew-tate-kickboxing-record-facts-height-weight-age-biography/\", \"content\": \"Who is Andrew Tate? Andrew Tate is a businessman, internet personality, and former professional kickboxer. Where is Andrew Tate From? Who is Andrew Tate\\u2019s Father? Andrew Tate Kickboxing Record What Kickboxing Gym Did Andrew Tate Train Out Of? How Many Professional Kickboxing Matches Has Andrew Tate Participated In? Andrew Tate competed in a total of 86 professional kickboxing bouts. What is Andrew Tate\\u2019 Professional Kickboxing Record? What Weight Classes Did Andrew Tate Compete In? In his professional kickboxing career, Andrew Tate won 32 of his fights by knockout. Did Andrew Tate Compete For Any Championship Titles? Did Tate Ever Compete In MMA? Andrew Tate competed in 1 professional MMA bout. How Much Money Did Andrew Tate Make In Kickboxing?\", \"score\": 0.50930125, \"raw_content\": null}, {\"title\": \"Andrew Tate - Wikipedia\", \"url\": \"https://en.wikipedia.org/wiki/Andrew_Tate\", \"content\": \"In 2011, Tate won his first International Sport Kickboxing Association (ISKA) world title in a rematch against Jean-Luc Beno\\u00eet via knockout, having previously lost to Beno\\u00eet by decision.[41] In 2012, Tate lost to Sahak Parparyan by unanimous decision while challenging for his It's Showtime 85MAX Championship.[42] Later that year, Tate lost the Enfusion championship tournament to Franci Graj\\u0161.[1] Before his loss, he was ranked second-best light-heavyweight kickboxer in the world.[43] In 2013, Tate won his second ISKA world title in a 12-round match against Vincent Petitjean, making him world champion in two weight divisions.[44] He defended the ISKA Belt and Won the Enfusion Belt in 2014, making him a four-time world champion[45] before he retired with 31 recorded fights.[46]\", \"score\": 0.49904844, \"raw_content\": null}]}\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33mAndrew\u001b[0m\u001b[33m Tate\u001b[0m\u001b[33m's\u001b[0m\u001b[33m kick\u001b[0m\u001b[33mboxing\u001b[0m\u001b[33m name\u001b[0m\u001b[33m is\u001b[0m\u001b[33m \"\u001b[0m\u001b[33mKing\u001b[0m\u001b[33m Cobra\u001b[0m\u001b[33m\".\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m" - ] - } - ], - "source": [ - "from llama_stack_client import Agent, AgentEventLogger\n", - "\n", - "agent = Agent(\n", - " client,\n", - " model=\"meta-llama/Llama-3.3-70B-Instruct\",\n", - " instructions=\"You are a helpful assistant. Use web_search tool to answer the questions.\",\n", - " tools=[\"builtin::websearch\"],\n", - ")\n", - "user_prompts = [\n", - " \"Which teams played in the NBA western conference finals of 2024. Search the web for the answer.\",\n", - " \"In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title. Search the web for the answer.\",\n", - " \"What is the British-American kickboxer Andrew Tate's kickboxing name? Search the web for the answer.\",\n", - "]\n", - "\n", - "session_id = agent.create_session(uuid.uuid4().hex)\n", - "\n", - "for prompt in user_prompts:\n", - " response = agent.create_turn(\n", - " messages=[\n", - " {\n", - " \"role\": \"user\",\n", - " \"content\": prompt,\n", - " }\n", - " ],\n", - " session_id=session_id,\n", - " )\n", - "\n", - " for log in AgentEventLogger().log(response):\n", - " log.print()\n" - ] - }, - { - "cell_type": "markdown", - "id": "d0a50faf", - "metadata": {}, - "source": [ - "##### 3.1.2 Query Agent Execution Steps\n", - "\n", - "Now, let's look deeper into the agent's execution steps and see if how well our agent performs. As a sanity check, we will first check if all user prompts is followed by a tool call to `brave_search`." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "c28ea2d1", - "metadata": {}, - "outputs": [], - "source": [ - "# query the agents session\n", - "from rich.pretty import pprint\n", - "\n", - "session_response = client.agents.session.retrieve(\n", - " session_id=session_id,\n", - " agent_id=agent.agent_id,\n", - ")\n", - "\n", - "pprint(session_response.turns)" - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "id": "f87a376d", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "3/3 user prompts are followed by a tool call to `brave_search`\n" - ] - } - ], - "source": [ - "num_tool_call = 0\n", - "for turn in session_response.turns:\n", - " for step in turn.steps:\n", - " if step.step_type == \"tool_execution\" and step.tool_calls[0].tool_name == \"brave_search\":\n", - " num_tool_call += 1\n", - "\n", - "print(f\"{num_tool_call}/{len(session_response.turns)} user prompts are followed by a tool call to `brave_search`\")" - ] - }, - { - "cell_type": "markdown", - "id": "ed69220f", - "metadata": {}, - "source": [ - "##### 3.1.3 Evaluate Agent Responses\n", - "\n", - "Now, we want to evaluate the agent's responses to the user prompts. \n", - "\n", - "1. First, we will process the agent's execution history into a list of rows that can be used for evaluation.\n", - "2. Next, we will label the rows with the expected answer.\n", - "3. Finally, we will use the `/scoring` API to score the agent's responses." - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "a2b293bc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
[\n",
-       "{\n",
-       "│   │   'input_query': 'Which teams played in the NBA western conference finals of 2024. Search the web for the answer.',\n",
-       "│   │   'generated_answer': 'The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.',\n",
-       "│   │   'expected_answer': 'Dallas Mavericks and the Minnesota Timberwolves'\n",
-       "},\n",
-       "{\n",
-       "│   │   'input_query': 'In which episode and season of South Park does Bill Cosby (BSM-471) first appear? Give me the number and title. Search the web for the answer.',\n",
-       "│   │   'generated_answer': 'Bill Cosby first appears in the episode \"Trapped in the Closet\" (Season 9, Episode 12) of South Park.',\n",
-       "│   │   'expected_answer': 'Season 4, Episode 12'\n",
-       "},\n",
-       "{\n",
-       "│   │   'input_query': \"What is the British-American kickboxer Andrew Tate's kickboxing name? Search the web for the answer.\",\n",
-       "│   │   'generated_answer': 'Andrew Tate\\'s kickboxing name is \"King Cobra\".',\n",
-       "│   │   'expected_answer': 'King Cobra'\n",
-       "}\n",
-       "]\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input_query'\u001b[0m: \u001b[32m'Which teams played in the NBA western conference finals of 2024. Search the web for the answer.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'generated_answer'\u001b[0m: \u001b[32m'The teams that played in the NBA Western Conference Finals of 2024 were the Dallas Mavericks and the Minnesota Timberwolves.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'expected_answer'\u001b[0m: \u001b[32m'Dallas Mavericks and the Minnesota Timberwolves'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input_query'\u001b[0m: \u001b[32m'In which episode and season of South Park does Bill Cosby \u001b[0m\u001b[32m(\u001b[0m\u001b[32mBSM-471\u001b[0m\u001b[32m)\u001b[0m\u001b[32m first appear? Give me the number and title. Search the web for the answer.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'generated_answer'\u001b[0m: \u001b[32m'Bill Cosby first appears in the episode \"Trapped in the Closet\" \u001b[0m\u001b[32m(\u001b[0m\u001b[32mSeason 9, Episode 12\u001b[0m\u001b[32m)\u001b[0m\u001b[32m of South Park.'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'expected_answer'\u001b[0m: \u001b[32m'Season 4, Episode 12'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input_query'\u001b[0m: \u001b[32m\"What is the British-American kickboxer Andrew Tate's kickboxing name? Search the web for the answer.\"\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'generated_answer'\u001b[0m: \u001b[32m'Andrew Tate\\'s kickboxing name is \"King Cobra\".'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'expected_answer'\u001b[0m: \u001b[32m'King Cobra'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[1m]\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
ScoringScoreResponse(\n",
-       "results={\n",
-       "│   │   'basic::subset_of': ScoringResult(\n",
-       "│   │   │   aggregated_results={'accuracy': {'accuracy': 0.6666666666666666, 'num_correct': 2.0, 'num_total': 3}},\n",
-       "│   │   │   score_rows=[{'score': 1.0}, {'score': 0.0}, {'score': 1.0}]\n",
-       "│   │   )\n",
-       "}\n",
-       ")\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1;35mScoringScoreResponse\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mresults\u001b[0m=\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'basic::subset_of'\u001b[0m: \u001b[1;35mScoringResult\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33maggregated_results\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1;36m0.6666666666666666\u001b[0m, \u001b[32m'num_correct'\u001b[0m: \u001b[1;36m2.0\u001b[0m, \u001b[32m'num_total'\u001b[0m: \u001b[1;36m3\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mscore_rows\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m0.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[1m)\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "eval_rows = []\n", - "\n", - "expected_answers = [\n", - " \"Dallas Mavericks and the Minnesota Timberwolves\",\n", - " \"Season 4, Episode 12\",\n", - " \"King Cobra\",\n", - "]\n", - "\n", - "for i, turn in enumerate(session_response.turns):\n", - " eval_rows.append(\n", - " {\n", - " \"input_query\": turn.input_messages[0].content,\n", - " \"generated_answer\": turn.output_message.content,\n", - " \"expected_answer\": expected_answers[i],\n", - " }\n", - " )\n", - "\n", - "pprint(eval_rows)\n", - "\n", - "scoring_params = {\n", - " \"basic::subset_of\": None,\n", - "}\n", - "scoring_response = client.scoring.score(\n", - " input_rows=eval_rows, scoring_functions=scoring_params\n", - ")\n", - "pprint(scoring_response)" - ] - }, - { - "cell_type": "markdown", - "id": "ekOS2kM4P0LM", - "metadata": { - "id": "ekOS2kM4P0LM" - }, - "source": [ - "##### 3.1.4 Query Telemetry & Evaluate\n", - "\n", - "Another way to get the agent's execution history is to query the telemetry logs from the `/telemetry` API. The following example shows how to query the telemetry logs and post-process them to prepare data for evaluation." - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "id": "agkWgToGAsuA", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "id": "agkWgToGAsuA", - "outputId": "4233a1d9-8282-4aa9-bdc4-0c105939f97e" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Getting traces for session_id=d73d9aaa-65ac-4255-8153-9f5cbff6e01e\n", - "Here are examples of traces:\n" - ] - }, - { - "data": { - "text/html": [ - "
[\n",
-       "{\n",
-       "│   │   'input': '[{\"role\": \"system\", \"content\": \"You are a helpful assistant. Use web_search tool to answer the questions.\"}, {\"role\": \"user\", \"content\": \"Which teams played in the NBA western conference finals of 2024. Search the web for the answer.\", \"context\": null}]',\n",
-       "│   │   'output': '{\"content\": \"\", \"tool_calls\": [{\"call_id\": \"5f77ab69-72d9-4d51-b96c-bd4352ced54a\", \"tool_name\": \"brave_search\", \"arguments\": {\"query\": \"NBA Western Conference Finals 2024 teams\"}, \"arguments_json\": \"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\"}\"}]}'\n",
-       "},\n",
-       "{\n",
-       "│   │   'input': '{\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":[{\"call_id\":\"5f77ab69-72d9-4d51-b96c-bd4352ced54a\",\"tool_name\":\"brave_search\",\"arguments\":{\"query\":\"NBA Western Conference Finals 2024 teams\"},\"arguments_json\":\"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\"}\"}]}',\n",
-       "│   │   'output': '{\"role\":\"tool\",\"call_id\":\"5f77ab69-72d9-4d51-b96c-bd4352ced54a\",\"content\":\"{\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": [{\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks (4-1) vs. 7   Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\\\\\\\u00a0Reference\\\\\\\\u202f\\\\\\\\u00ae Baseball Football (college) Basketball (college) Hockey F\\\\\\\\u00fatbol Blog Stathead\\\\\\\\u202f\\\\\\\\u00ae Immaculate Grid\\\\\\\\u202f\\\\\\\\u00ae\\\\\", \\\\\"score\\\\\": 0.89030397, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"NBA Standings - 2024-25 season - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/standings\\\\\", \\\\\"content\\\\\": \\\\\"NBA Standings - 2024-25 season - ESPN Skip to main contentSkip to navigation ESPN NFL NBA NCAAF NHL NCAAM NCAAW Soccer More Sports Watch Fantasy NBA Home Scores Schedule Standings Stats Teams Odds Where To Watch All-Star Game Fantasy More NBA Standings 2024-25 Standings Expanded Vs. Division NBA Cup LeagueConferenceDivision Eastern Conference | | | --- | | 1CLECleveland Cavaliers | | 2BOSBoston Celtics | | 3NYNew York Knicks | | 4INDIndiana Pacers | | 5MILMilwaukee Bucks | | 6DETDetroit Pistons | | 7MIAMiami Heat | | 8ORLOrlando Magic | | 9ATLAtlanta Hawks | | 10CHIChicago Bulls | | PHIPhiladelphia 76ers | | BKNBrooklyn Nets | | TORToronto Raptors | | CHACharlotte Hornets | | WSHWashington Wizards | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 42 | 10 | .808 | - | 24-4 | 18-6 | 9-1 | 28-7 | 122.4 | 112.1 | +10.3 | W2 | 6-4 | | 36 | 16 | .692 | 6 | 16-10 | 20-6 | 6-2 | 26-9 | 117.3 | 108.8 | +8.5 | L1 | 7-3 | | 34 | 17 | .667 | 7.5 | 18-9 | 16-8 | 9-1 | 23-10 | 117.9 | 111.4 | +6.5 | W2 | 8-2 | | 29 | 21 | .580 | 12 | 14-7 | 14-13 | 6-4 | 17-15 | 115.7 | 114.9 | +0.8 | W1 | 7-3 | | 27 | 23 | .540 | 14 | 16-8 | 10-15 | 6-5 | 22-16 | 114.2 | 112.6 | +1.6 | L1 | 4-6 | | 26 | 26 | .500 | 16 | 13-13 | 13-13 | 2-9 | 18-20 | 113.0 | 113.8 | -0.8 | W1 | 5-5 | | 25 | 25 | .500 | 16 | 12-10 | 12-15 | 5-3 | 14-15 | 110.5 | 110.6 | -0.1 | L1 | 5-5 | | 25 | 28 | .472 | 17.5 | 15-9 | 10-19 | 5-2 | 20-15 | 103.8 | 105.6 | -1.8 | L1 | 2-8 | | 24 | 28 | .462 | 18 | 12-12 | 12-15 | 4-2 | 17-13 | 116.1 | 119.0 | -2.9 | W1 | 2-8 | | 22 | 30 | .423 | 20 | 10-16 | 12-14 | 3-7 | 17-18 | 116.7 | 120.1 | -3.4 | L1 | 4-6 | | 20 | 31 | .392 | 21.5 | 10-16 | 10-15 | 3-4 | 14-17 | 109.1 | 112.9 | -3.8 | L2 | 5-5 | | 18 | 34 | .346 | 24 | 7-17 | 11-17 | 1-8 | 9-23 | 105.3 | 111.7 | -6.4 | W1 | 4-6 | | 16 | 36 | .308 | 26 | 12-16 | 4-20 | 3-7 | 10-23 | 111.2 | 116.9 | -5.7 | L3 | 6-4 | | 13 | 36 | .265 | 27.5 | 9-20 | 4-16 | 0-9 | 7-27 | 107.1 | 112.3 | -5.2 | W1 | 2-8 | | 9 | 42 | .176 | 32.5 | 5-20 | 4-21 | 5-3 | 7-21 | 107.8 | 121.5 | -13.7 | L1 | 3-7 | Western Conference | | | --- | | 1OKCOklahoma City Thunder | | 2MEMMemphis Grizzlies | | 3DENDenver Nuggets | | 4HOUHouston Rockets | | 5LALLos Angeles Lakers | | 6MINMinnesota Timberwolves | | 7LACLA Clippers | | 8DALDallas Mavericks | | 9PHXPhoenix Suns | | 10SACSacramento Kings | | GSGolden State Warriors | | SASan Antonio Spurs | | PORPortland Trail Blazers | | UTAHUtah Jazz | | NONew Orleans Pelicans | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 41 | 9 | .820 | - | 23-3 | 17-6 | 7-1 | 23-8 | 117.7 | 104.7 | +13.0 | W4 | 7-3 | | 35 | 16 | .686 | 6.5 | 21-5 | 14-11 | 8-4 | 19-12 | 123.8 | 115.4 | +8.4 | W4 | 9-1 | | 33 | 19 | .635 | 9 | 17-8 | 16-11 | 4-4 | 19-12 | 120.8 | 115.9 | +4.9 | W5 | 7-3 | | 32 | 20 | .615 | 10 | 15-8 | 17-11 | 9-3 | 19-12 | 113.3 | 109.1 | +4.2 | L6 | 4-6 | | 30 | 19 | .612 | 10.5 | 17-6 | 13-13 | 9-3 | 19-11 | 112.6 | 112.0 | +0.6 | W4 | 8-2 | | 29 | 23 | .558 | 13 | 14-12 | 15-11 | 4-3 | 21-14 | 111.7 | 108.2 | +3.5 | W2 | 7-3 | | 28 | 23 | .549 | 13.5 | 17-10 | 11-13 | 6-4 | 17-18 | 110.1 | 107.7 | +2.4 | L3 | 4-6 | | 28 | 25 | .528 | 14.5 | 15-10 | 13-15 | 6-4 | 20-17 | 115.5 | 113.3 | +2.2 | W2 | 5-5 | | 26 | 25 | .510 | 15.5 | 16-9 | 10-16 | 7-4 | 17-14 | 113.4 | 114.7 | -1.3 | W1 | 5-5 | | 25 | 26 | .490 | 16.5 | 13-13 | 12-13 | 4-6 | 16-17 | 116.1 | 115.4 | +0.7 | L2 | 4-6 | | 25 | 26 | .490 | 16.5 | 15-13 | 10-13 | 1-10 | 17-18 | 111.5 | 111.9 | -0.4 | L2 | 4-6 | | 22 | 27 | .449 | 18.5 | 13-12 | 8-14 | 2-7 | 16-18 | 112.8 | 114.3 | -1.5 | L1 | 3-7 | | 23 | 29 | .442 | 19 | 15-13 | 8-16 | 4-5 | 14-24 | 109.0 | 113.9 | -4.9 | W6 | 9-1 | | 12 | 38 | .240 | 29 | 5-18 | 7-20 | 1-7 | 4-29 | 111.9 | 118.9 | -7.0 | L1 | 2-8 | | 12 | 39 | .235 | 29.5 | 8-18 | 4-21 | 1-8 | 6-23 | 110.0 | 118.8 | -8.8 | L7 | 3-7 | Standings are updated with the completion of each game.Teams seeded 7-10 in each conference will compete in a play-in tournament at the end of the regular season. Glossary W:Wins L:Losses PCT:Winning Percentage GB:Games Back HOME:Home Record AWAY:Away Record DIV:Division Record CONF:Conference Record PPG:Points Per Game OPP PPG:Opponent Points Per Game DIFF:Average Point Differential STRK:Current Streak L10:Record last 10 games NBA News Anthony Davis leads Mavericks past Rockets 116-105 in Mavs debut but leaves with lower-body injury -------------------------------------------------------------------------------------------------- \\\\\\\\u2014 Anthony Davis had 26 points, 16 rebounds, seven assists and three blocks in his Mavericks debut but left the game late in the third quarter with a... * 38m Hawks request waivers on newly acquired Bones Hyland ---------------------------------------------------- The Atlanta Hawks requested waivers on guard Bones Hyland on Saturday, just two days after the guard was obtained from the Clippers in a deal at the NBA trade deadline. * 1h AD posts 26-point double-double in debut before suffering injury ---------------------------------------------------------------- Anthony Davis has a strong debut with the Mavs, dropping 26 points, 16 rebounds and 7 assists, before leaving with a lower-body injury. * 1h All NBA News Terms of Use Privacy Policy Your US State Privacy Rights Children\\'s Online Privacy Policy Interest-Based Ads About Nielsen Measurement Do Not Sell or Share My Personal Information Contact Us Disney Ad Sales Site Work for ESPN Corrections ESPN BET Sportsbook is owned and operated by PENN Entertainment, Inc. and its subsidiaries (\\'PENN\\').\\\\\", \\\\\"score\\\\\": 0.83549726, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves (3) vs. Mavericks (5) | NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"Mavericks (5) | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: \\'This is special, coming from the West\\' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\\\\\", \\\\\"score\\\\\": 0.75312227, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2024 NBA Playoffs | Official Bracket, Schedule and Series Matchups\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024?os=wtmbloozowcj&ref=app\\\\\", \\\\\"content\\\\\": \\\\\"Draft Kings DFS NBA Store NBA Play NBA Finals ### Chasing History: Celtics clinch banner 18 (Ep. 25) Jayson Tatum and Finals MVP Jaylen Brown close out Dallas in Game 5 to secure Boston\\'s NBA-record 18th championship. WE DID ITTTT!\\' Jayson Tatum walkoff interview after Celtics defeat Mavericks in Game 5 of 2024 NBA Finals, clinching title with a 4-1 series win. ### Horford finally champ after key sacrifice Al Horford, who played the most playoff games in NBA history before winning his 1st title, crosses the plateau in his 17th season. 30:13 ### Best of the 2024 NBA Finals 17:47 ### Best of Boston Celtics from the 2024 NBA Finals\\\\\", \\\\\"score\\\\\": 0.63234437, \\\\\"raw_content\\\\\": null}, {\\\\\"title\\\\\": \\\\\"2025 NBA Playoffs: Standings, bracket and clinching updates\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/news/2025-nba-playoffs-standings-and-bracket-updates\\\\\", \\\\\"content\\\\\": \\\\\"NBA TV NBA Play NBA Store NBA Game Worn NBA Play NBA Official NBA Playoffs bracket ### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. Click \\\\\\\\\\\\\"Access Content\\\\\\\\\\\\\" to agree to our Terms of Use and Privacy Policy and to sign up for emails about the latest news and products from the NBA Family and its partners. #### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. NBA ID NBA Official NBA Transactions NBA Auctions\\\\\", \\\\\"score\\\\\": 0.13435538, \\\\\"raw_content\\\\\": null}]}\"}'\n",
-       "}\n",
-       "]\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\": \"system\", \"content\": \"You are a helpful assistant. Use web_search tool to answer the questions.\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\": \"user\", \"content\": \"Which teams played in the NBA western conference finals of 2024. Search the web for the answer.\", \"context\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"content\": \"\", \"tool_calls\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\": \"5f77ab69-72d9-4d51-b96c-bd4352ced54a\", \"tool_name\": \"brave_search\", \"arguments\": \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\": \"NBA Western Conference Finals 2024 teams\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \"arguments_json\": \"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'input'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"assistant\",\"content\":\"\",\"stop_reason\":\"end_of_turn\",\"tool_calls\":\u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"call_id\":\"5f77ab69-72d9-4d51-b96c-bd4352ced54a\",\"tool_name\":\"brave_search\",\"arguments\":\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"query\":\"NBA Western Conference Finals 2024 teams\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m,\"arguments_json\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'output'\u001b[0m: \u001b[32m'\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\"role\":\"tool\",\"call_id\":\"5f77ab69-72d9-4d51-b96c-bd4352ced54a\",\"content\":\"\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"query\\\\\": \\\\\"NBA Western Conference Finals 2024 teams\\\\\", \\\\\"top_k\\\\\": \u001b[0m\u001b[32m[\u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Western Conference Finals - Basketball-Reference.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.basketball-reference.com/playoffs/2024-nba-western-conference-finals-mavericks-vs-timberwolves.html\\\\\", \\\\\"content\\\\\": \\\\\"2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. 5 Dallas Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m4-1\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. 7 Derrick Jones Jr. 2024 NBA Playoffs Dallas Mavericks vs. Dallas Mavericks vs. Dallas Mavericks vs. College Tools: Player Season Finder, Player Game Finder, Team Season Finder, Team Game Finder Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards ... Players, Teams, Seasons, Leaders, Awards, All-Star Games, Executives ... Players, Teams, Seasons, Leaders, Awards ... Subscribe to Stathead Basketball: Get your first month FREE The SPORTS REFERENCE, STATHEAD, IMMACULATE GRID, and IMMACULATE FOOTY trademarks are owned exclusively by Sports Reference LLC. Sports\\\\\\\\u00a0Reference\\\\\\\\u202f\\\\\\\\u00ae Baseball Football \u001b[0m\u001b[32m(\u001b[0m\u001b[32mcollege\u001b[0m\u001b[32m)\u001b[0m\u001b[32m Basketball \u001b[0m\u001b[32m(\u001b[0m\u001b[32mcollege\u001b[0m\u001b[32m)\u001b[0m\u001b[32m Hockey F\\\\\\\\u00fatbol Blog Stathead\\\\\\\\u202f\\\\\\\\u00ae Immaculate Grid\\\\\\\\u202f\\\\\\\\u00ae\\\\\", \\\\\"score\\\\\": 0.89030397, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"NBA Standings - 2024-25 season - ESPN\\\\\", \\\\\"url\\\\\": \\\\\"https://www.espn.com/nba/standings\\\\\", \\\\\"content\\\\\": \\\\\"NBA Standings - 2024-25 season - ESPN Skip to main contentSkip to navigation ESPN NFL NBA NCAAF NHL NCAAM NCAAW Soccer More Sports Watch Fantasy NBA Home Scores Schedule Standings Stats Teams Odds Where To Watch All-Star Game Fantasy More NBA Standings 2024-25 Standings Expanded Vs. Division NBA Cup LeagueConferenceDivision Eastern Conference | | | --- | | 1CLECleveland Cavaliers | | 2BOSBoston Celtics | | 3NYNew York Knicks | | 4INDIndiana Pacers | | 5MILMilwaukee Bucks | | 6DETDetroit Pistons | | 7MIAMiami Heat | | 8ORLOrlando Magic | | 9ATLAtlanta Hawks | | 10CHIChicago Bulls | | PHIPhiladelphia 76ers | | BKNBrooklyn Nets | | TORToronto Raptors | | CHACharlotte Hornets | | WSHWashington Wizards | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 42 | 10 | .808 | - | 24-4 | 18-6 | 9-1 | 28-7 | 122.4 | 112.1 | +10.3 | W2 | 6-4 | | 36 | 16 | .692 | 6 | 16-10 | 20-6 | 6-2 | 26-9 | 117.3 | 108.8 | +8.5 | L1 | 7-3 | | 34 | 17 | .667 | 7.5 | 18-9 | 16-8 | 9-1 | 23-10 | 117.9 | 111.4 | +6.5 | W2 | 8-2 | | 29 | 21 | .580 | 12 | 14-7 | 14-13 | 6-4 | 17-15 | 115.7 | 114.9 | +0.8 | W1 | 7-3 | | 27 | 23 | .540 | 14 | 16-8 | 10-15 | 6-5 | 22-16 | 114.2 | 112.6 | +1.6 | L1 | 4-6 | | 26 | 26 | .500 | 16 | 13-13 | 13-13 | 2-9 | 18-20 | 113.0 | 113.8 | -0.8 | W1 | 5-5 | | 25 | 25 | .500 | 16 | 12-10 | 12-15 | 5-3 | 14-15 | 110.5 | 110.6 | -0.1 | L1 | 5-5 | | 25 | 28 | .472 | 17.5 | 15-9 | 10-19 | 5-2 | 20-15 | 103.8 | 105.6 | -1.8 | L1 | 2-8 | | 24 | 28 | .462 | 18 | 12-12 | 12-15 | 4-2 | 17-13 | 116.1 | 119.0 | -2.9 | W1 | 2-8 | | 22 | 30 | .423 | 20 | 10-16 | 12-14 | 3-7 | 17-18 | 116.7 | 120.1 | -3.4 | L1 | 4-6 | | 20 | 31 | .392 | 21.5 | 10-16 | 10-15 | 3-4 | 14-17 | 109.1 | 112.9 | -3.8 | L2 | 5-5 | | 18 | 34 | .346 | 24 | 7-17 | 11-17 | 1-8 | 9-23 | 105.3 | 111.7 | -6.4 | W1 | 4-6 | | 16 | 36 | .308 | 26 | 12-16 | 4-20 | 3-7 | 10-23 | 111.2 | 116.9 | -5.7 | L3 | 6-4 | | 13 | 36 | .265 | 27.5 | 9-20 | 4-16 | 0-9 | 7-27 | 107.1 | 112.3 | -5.2 | W1 | 2-8 | | 9 | 42 | .176 | 32.5 | 5-20 | 4-21 | 5-3 | 7-21 | 107.8 | 121.5 | -13.7 | L1 | 3-7 | Western Conference | | | --- | | 1OKCOklahoma City Thunder | | 2MEMMemphis Grizzlies | | 3DENDenver Nuggets | | 4HOUHouston Rockets | | 5LALLos Angeles Lakers | | 6MINMinnesota Timberwolves | | 7LACLA Clippers | | 8DALDallas Mavericks | | 9PHXPhoenix Suns | | 10SACSacramento Kings | | GSGolden State Warriors | | SASan Antonio Spurs | | PORPortland Trail Blazers | | UTAHUtah Jazz | | NONew Orleans Pelicans | | W | L | PCT | GB | HOME | AWAY | DIV | CONF | PPG | OPP PPG | DIFF | STRK | L10 | | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 41 | 9 | .820 | - | 23-3 | 17-6 | 7-1 | 23-8 | 117.7 | 104.7 | +13.0 | W4 | 7-3 | | 35 | 16 | .686 | 6.5 | 21-5 | 14-11 | 8-4 | 19-12 | 123.8 | 115.4 | +8.4 | W4 | 9-1 | | 33 | 19 | .635 | 9 | 17-8 | 16-11 | 4-4 | 19-12 | 120.8 | 115.9 | +4.9 | W5 | 7-3 | | 32 | 20 | .615 | 10 | 15-8 | 17-11 | 9-3 | 19-12 | 113.3 | 109.1 | +4.2 | L6 | 4-6 | | 30 | 19 | .612 | 10.5 | 17-6 | 13-13 | 9-3 | 19-11 | 112.6 | 112.0 | +0.6 | W4 | 8-2 | | 29 | 23 | .558 | 13 | 14-12 | 15-11 | 4-3 | 21-14 | 111.7 | 108.2 | +3.5 | W2 | 7-3 | | 28 | 23 | .549 | 13.5 | 17-10 | 11-13 | 6-4 | 17-18 | 110.1 | 107.7 | +2.4 | L3 | 4-6 | | 28 | 25 | .528 | 14.5 | 15-10 | 13-15 | 6-4 | 20-17 | 115.5 | 113.3 | +2.2 | W2 | 5-5 | | 26 | 25 | .510 | 15.5 | 16-9 | 10-16 | 7-4 | 17-14 | 113.4 | 114.7 | -1.3 | W1 | 5-5 | | 25 | 26 | .490 | 16.5 | 13-13 | 12-13 | 4-6 | 16-17 | 116.1 | 115.4 | +0.7 | L2 | 4-6 | | 25 | 26 | .490 | 16.5 | 15-13 | 10-13 | 1-10 | 17-18 | 111.5 | 111.9 | -0.4 | L2 | 4-6 | | 22 | 27 | .449 | 18.5 | 13-12 | 8-14 | 2-7 | 16-18 | 112.8 | 114.3 | -1.5 | L1 | 3-7 | | 23 | 29 | .442 | 19 | 15-13 | 8-16 | 4-5 | 14-24 | 109.0 | 113.9 | -4.9 | W6 | 9-1 | | 12 | 38 | .240 | 29 | 5-18 | 7-20 | 1-7 | 4-29 | 111.9 | 118.9 | -7.0 | L1 | 2-8 | | 12 | 39 | .235 | 29.5 | 8-18 | 4-21 | 1-8 | 6-23 | 110.0 | 118.8 | -8.8 | L7 | 3-7 | Standings are updated with the completion of each game.Teams seeded 7-10 in each conference will compete in a play-in tournament at the end of the regular season. Glossary W:Wins L:Losses PCT:Winning Percentage GB:Games Back HOME:Home Record AWAY:Away Record DIV:Division Record CONF:Conference Record PPG:Points Per Game OPP PPG:Opponent Points Per Game DIFF:Average Point Differential STRK:Current Streak L10:Record last 10 games NBA News Anthony Davis leads Mavericks past Rockets 116-105 in Mavs debut but leaves with lower-body injury -------------------------------------------------------------------------------------------------- \\\\\\\\u2014 Anthony Davis had 26 points, 16 rebounds, seven assists and three blocks in his Mavericks debut but left the game late in the third quarter with a... * 38m Hawks request waivers on newly acquired Bones Hyland ---------------------------------------------------- The Atlanta Hawks requested waivers on guard Bones Hyland on Saturday, just two days after the guard was obtained from the Clippers in a deal at the NBA trade deadline. * 1h AD posts 26-point double-double in debut before suffering injury ---------------------------------------------------------------- Anthony Davis has a strong debut with the Mavs, dropping 26 points, 16 rebounds and 7 assists, before leaving with a lower-body injury. * 1h All NBA News Terms of Use Privacy Policy Your US State Privacy Rights Children\\'s Online Privacy Policy Interest-Based Ads About Nielsen Measurement Do Not Sell or Share My Personal Information Contact Us Disney Ad Sales Site Work for ESPN Corrections ESPN BET Sportsbook is owned and operated by PENN Entertainment, Inc. and its subsidiaries \u001b[0m\u001b[32m(\u001b[0m\u001b[32m\\'PENN\\'\u001b[0m\u001b[32m)\u001b[0m\u001b[32m.\\\\\", \\\\\"score\\\\\": 0.83549726, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 Playoffs: West Finals | Timberwolves \u001b[0m\u001b[32m(\u001b[0m\u001b[32m3\u001b[0m\u001b[32m)\u001b[0m\u001b[32m vs. Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | NBA.com\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024/west-final\\\\\", \\\\\"content\\\\\": \\\\\"Mavericks \u001b[0m\u001b[32m(\u001b[0m\u001b[32m5\u001b[0m\u001b[32m)\u001b[0m\u001b[32m | NBA.com 2024-25 NBA CrunchTime NBA TV Draft Kings DFS NBA Bet Home NBA Store NBA Game Worn NBA Photo Store NBA Experiences NBA G League NBA 2K League NBA Play NBA Bet ### Doncic, Irving carry Mavs to NBA Finals Luka Doncic and Kyrie Irving pour in 36 points apiece to guide Dallas to its 1st appearance in the NBA Finals since 2011. ### Luka: \\'This is special, coming from the West\\' Luka Doncic with Ernie, Charles, Kenny & Shaq about the Mavs being NBA Finals-bound, his Game 5 play and more. NBA Organization NBA ID NBA Official NBA Careers NBA Initiatives NBA Cares NBA Foundation NBA Communications NBA Transactions NBA Auctions NBA Photostore\\\\\", \\\\\"score\\\\\": 0.75312227, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2024 NBA Playoffs | Official Bracket, Schedule and Series Matchups\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/playoffs/2024?\u001b[0m\u001b[32mos\u001b[0m\u001b[32m=\u001b[0m\u001b[32mwtmbloozowcj\u001b[0m\u001b[32m&\u001b[0m\u001b[32mref\u001b[0m\u001b[32m=\u001b[0m\u001b[32mapp\u001b[0m\u001b[32m\\\\\", \\\\\"content\\\\\": \\\\\"Draft Kings DFS NBA Store NBA Play NBA Finals ### Chasing History: Celtics clinch banner 18 \u001b[0m\u001b[32m(\u001b[0m\u001b[32mEp. 25\u001b[0m\u001b[32m)\u001b[0m\u001b[32m Jayson Tatum and Finals MVP Jaylen Brown close out Dallas in Game 5 to secure Boston\\'s NBA-record 18th championship. WE DID ITTTT!\\' Jayson Tatum walkoff interview after Celtics defeat Mavericks in Game 5 of 2024 NBA Finals, clinching title with a 4-1 series win. ### Horford finally champ after key sacrifice Al Horford, who played the most playoff games in NBA history before winning his 1st title, crosses the plateau in his 17th season. 30:13 ### Best of the 2024 NBA Finals 17:47 ### Best of Boston Celtics from the 2024 NBA Finals\\\\\", \\\\\"score\\\\\": 0.63234437, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m, \u001b[0m\u001b[32m{\u001b[0m\u001b[32m\\\\\"title\\\\\": \\\\\"2025 NBA Playoffs: Standings, bracket and clinching updates\\\\\", \\\\\"url\\\\\": \\\\\"https://www.nba.com/news/2025-nba-playoffs-standings-and-bracket-updates\\\\\", \\\\\"content\\\\\": \\\\\"NBA TV NBA Play NBA Store NBA Game Worn NBA Play NBA Official NBA Playoffs bracket ### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. Click \\\\\\\\\\\\\"Access Content\\\\\\\\\\\\\" to agree to our Terms of Use and Privacy Policy and to sign up for emails about the latest news and products from the NBA Family and its partners. #### What to know about 2025 SoFi NBA Play-In Tournament The SoFi NBA Play-In Tournament features the Nos. 7-10 teams in each conference battling for the 7th and 8th playoff seeds. NBA ID NBA Official NBA Transactions NBA Auctions\\\\\", \\\\\"score\\\\\": 0.13435538, \\\\\"raw_content\\\\\": null\u001b[0m\u001b[32m}\u001b[0m\u001b[32m]\u001b[0m\u001b[32m}\u001b[0m\u001b[32m\"\u001b[0m\u001b[32m}\u001b[0m\u001b[32m'\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[1m]\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# NBVAL_SKIP\n", - "print(f\"Getting traces for session_id={session_id}\")\n", - "import json\n", - "\n", - "from rich.pretty import pprint\n", - "\n", - "agent_logs = []\n", - "\n", - "for span in client.telemetry.query_spans(\n", - " attribute_filters=[\n", - " {\"key\": \"session_id\", \"op\": \"eq\", \"value\": session_id},\n", - " ],\n", - " attributes_to_return=[\"input\", \"output\"],\n", - "):\n", - " if span.attributes[\"output\"] != \"no shields\":\n", - " agent_logs.append(span.attributes)\n", - "\n", - "print(\"Here are examples of traces:\")\n", - "pprint(agent_logs[:2])\n" - ] - }, - { - "cell_type": "markdown", - "id": "QF30H7ufP2RE", - "metadata": { - "id": "QF30H7ufP2RE" - }, - "source": [ - "- Now, we want to run evaluation to assert that our search agent succesfully calls brave_search from online traces.\n", - "- We will first post-process the agent's telemetry logs and run evaluation." - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "sy4Xaff_Avuu", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 432 - }, - "id": "sy4Xaff_Avuu", - "outputId": "1b14b5ed-4c77-47c4-edfb-1c13a88e5ef4" - }, - "outputs": [ - { - "data": { - "text/html": [ - "
ScoringScoreResponse(\n",
-       "results={\n",
-       "│   │   'basic::subset_of': ScoringResult(\n",
-       "│   │   │   aggregated_results={'accuracy': {'accuracy': 1.0, 'num_correct': 3.0, 'num_total': 3}},\n",
-       "│   │   │   score_rows=[{'score': 1.0}, {'score': 1.0}, {'score': 1.0}]\n",
-       "│   │   )\n",
-       "}\n",
-       ")\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1;35mScoringScoreResponse\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mresults\u001b[0m=\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'basic::subset_of'\u001b[0m: \u001b[1;35mScoringResult\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33maggregated_results\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'num_correct'\u001b[0m: \u001b[1;36m3.0\u001b[0m, \u001b[32m'num_total'\u001b[0m: \u001b[1;36m3\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mscore_rows\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m, \u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[1m)\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "# NBVAL_SKIP\n", - "# post-process telemetry spance and prepare data for eval\n", - "# in this case, we want to assert that all user prompts is followed by a tool call\n", - "import ast\n", - "import json\n", - "\n", - "eval_rows = []\n", - "\n", - "for log in agent_logs:\n", - " input = json.loads(log[\"input\"])\n", - " if isinstance(input, list):\n", - " input = input[-1]\n", - " if input[\"role\"] == \"user\":\n", - " eval_rows.append(\n", - " {\n", - " \"input_query\": input[\"content\"],\n", - " \"generated_answer\": log[\"output\"],\n", - " # check if generated_answer uses tools brave_search\n", - " \"expected_answer\": \"brave_search\",\n", - " },\n", - " )\n", - "\n", - "# pprint(eval_rows)\n", - "scoring_params = {\n", - " \"basic::subset_of\": None,\n", - "}\n", - "scoring_response = client.scoring.score(\n", - " input_rows=eval_rows, scoring_functions=scoring_params\n", - ")\n", - "pprint(scoring_response)\n" - ] - }, - { - "cell_type": "markdown", - "id": "IKbzhxcw5e_c", - "metadata": { - "id": "IKbzhxcw5e_c" - }, - "source": [ - "#### 3.2. Agentic Application Dataset Scoring\n", - "- Llama Stack offers a library of scoring functions and the `/scoring` API, allowing you to run evaluations on your pre-annotated AI application datasets.\n", - "\n", - "- In this example, we will work with an example RAG dataset you have built previously, label with an annotation, and use LLM-As-Judge with custom judge prompt for scoring. Please checkout our [Llama Stack Playground](https://llama-stack.readthedocs.io/en/latest/playground/index.html) for an interactive interface to upload datasets and run scorings." - ] - }, - { - "cell_type": "code", - "execution_count": 28, - "id": "xG4Y84VQBb0g", - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 304 - }, - "id": "xG4Y84VQBb0g", - "outputId": "cf7dcecc-a81d-4c60-af5e-b36b8fe85c69" - }, - "outputs": [ - { - "data": { - "text/html": [ - "
ScoringScoreResponse(\n",
-       "results={\n",
-       "│   │   'llm-as-judge::base': ScoringResult(\n",
-       "│   │   │   aggregated_results={},\n",
-       "│   │   │   score_rows=[\n",
-       "│   │   │   │   {\n",
-       "│   │   │   │   │   'score': 'B',\n",
-       "│   │   │   │   │   'judge_feedback': 'Answer: B, Explanation: The GENERATED_RESPONSE is a superset of the EXPECTED_RESPONSE and is fully consistent with it. The EXPECTED_RESPONSE only mentions \"LoRA\", which is a topic that is extensively covered in the GENERATED_RESPONSE. The GENERATED_RESPONSE provides more specific and detailed topics related to LoRA, but it does not contradict the EXPECTED_RESPONSE.'\n",
-       "│   │   │   │   }\n",
-       "│   │   │   ]\n",
-       "│   │   ),\n",
-       "│   │   'basic::subset_of': ScoringResult(\n",
-       "│   │   │   aggregated_results={'accuracy': {'accuracy': 1.0, 'num_correct': 1.0, 'num_total': 1}},\n",
-       "│   │   │   score_rows=[{'score': 1.0}]\n",
-       "│   │   )\n",
-       "}\n",
-       ")\n",
-       "
\n" - ], - "text/plain": [ - "\u001b[1;35mScoringScoreResponse\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[33mresults\u001b[0m=\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'llm-as-judge::base'\u001b[0m: \u001b[1;35mScoringResult\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33maggregated_results\u001b[0m=\u001b[1m{\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mscore_rows\u001b[0m=\u001b[1m[\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m{\u001b[0m\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[32m'score'\u001b[0m: \u001b[32m'B'\u001b[0m,\n", - "\u001b[2;32m│ │ │ │ │ \u001b[0m\u001b[32m'judge_feedback'\u001b[0m: \u001b[32m'Answer: B, Explanation: The GENERATED_RESPONSE is a superset of the EXPECTED_RESPONSE and is fully consistent with it. The EXPECTED_RESPONSE only mentions \"LoRA\", which is a topic that is extensively covered in the GENERATED_RESPONSE. The GENERATED_RESPONSE provides more specific and detailed topics related to LoRA, but it does not contradict the EXPECTED_RESPONSE.'\u001b[0m\n", - "\u001b[2;32m│ │ │ │ \u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m,\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[32m'basic::subset_of'\u001b[0m: \u001b[1;35mScoringResult\u001b[0m\u001b[1m(\u001b[0m\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33maggregated_results\u001b[0m=\u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1m{\u001b[0m\u001b[32m'accuracy'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'num_correct'\u001b[0m: \u001b[1;36m1.0\u001b[0m, \u001b[32m'num_total'\u001b[0m: \u001b[1;36m1\u001b[0m\u001b[1m}\u001b[0m\u001b[1m}\u001b[0m,\n", - "\u001b[2;32m│ │ │ \u001b[0m\u001b[33mscore_rows\u001b[0m=\u001b[1m[\u001b[0m\u001b[1m{\u001b[0m\u001b[32m'score'\u001b[0m: \u001b[1;36m1.0\u001b[0m\u001b[1m}\u001b[0m\u001b[1m]\u001b[0m\n", - "\u001b[2;32m│ │ \u001b[0m\u001b[1m)\u001b[0m\n", - "\u001b[2;32m│ \u001b[0m\u001b[1m}\u001b[0m\n", - "\u001b[1m)\u001b[0m\n" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import rich\n", - "from rich.pretty import pprint\n", - "\n", - "# could even use larger models like 405B\n", - "judge_model_id = \"meta-llama/Llama-3.3-70B-Instruct\"\n", - "\n", - "JUDGE_PROMPT = \"\"\"\n", - "Given a QUESTION and GENERATED_RESPONSE and EXPECTED_RESPONSE.\n", - "\n", - "Compare the factual content of the GENERATED_RESPONSE with the EXPECTED_RESPONSE. Ignore any differences in style, grammar, or punctuation.\n", - " The GENERATED_RESPONSE may either be a subset or superset of the EXPECTED_RESPONSE, or it may conflict with it. Determine which case applies. Answer the question by selecting one of the following options:\n", - " (A) The GENERATED_RESPONSE is a subset of the EXPECTED_RESPONSE and is fully consistent with it.\n", - " (B) The GENERATED_RESPONSE is a superset of the EXPECTED_RESPONSE and is fully consistent with it.\n", - " (C) The GENERATED_RESPONSE contains all the same details as the EXPECTED_RESPONSE.\n", - " (D) There is a disagreement between the GENERATED_RESPONSE and the EXPECTED_RESPONSE.\n", - " (E) The answers differ, but these differences don't matter from the perspective of factuality.\n", - "\n", - "Give your answer in the format \"Answer: One of ABCDE, Explanation: \".\n", - "\n", - "Your actual task:\n", - "\n", - "QUESTION: {input_query}\n", - "GENERATED_RESPONSE: {generated_answer}\n", - "EXPECTED_RESPONSE: {expected_answer}\n", - "\"\"\"\n", - "\n", - "input_query = (\n", - " \"What are the top 5 topics that were explained? Only list succinct bullet points.\"\n", - ")\n", - "generated_answer = \"\"\"\n", - "Here are the top 5 topics that were explained in the documentation for Torchtune:\n", - "\n", - "* What is LoRA and how does it work?\n", - "* Fine-tuning with LoRA: memory savings and parameter-efficient finetuning\n", - "* Running a LoRA finetune with Torchtune: overview and recipe\n", - "* Experimenting with different LoRA configurations: rank, alpha, and attention modules\n", - "* LoRA finetuning\n", - "\"\"\"\n", - "expected_answer = \"\"\"LoRA\"\"\"\n", - "\n", - "rows = [\n", - " {\n", - " \"input_query\": input_query,\n", - " \"generated_answer\": generated_answer,\n", - " \"expected_answer\": expected_answer,\n", - " },\n", - "]\n", - "\n", - "scoring_params = {\n", - " \"llm-as-judge::base\": {\n", - " \"judge_model\": judge_model_id,\n", - " \"prompt_template\": JUDGE_PROMPT,\n", - " \"type\": \"llm_as_judge\",\n", - " \"judge_score_regexes\": [\"Answer: (A|B|C|D|E)\"],\n", - " },\n", - " \"basic::subset_of\": None,\n", - "}\n", - "\n", - "response = client.scoring.score(input_rows=rows, scoring_functions=scoring_params)\n", - "pprint(response)\n" + " print(log, end=\"\", flush=True)\n" ] }, { @@ -2826,7 +2670,7 @@ "id": "ad077440", "metadata": {}, "source": [ - "## 4. Image Understanding with Llama 3.2\n", + "## 3. Image Understanding with Llama 3.2\n", "\n", "Below is a complete example of to ask Llama 3.2 questions about an image." ] @@ -2836,12 +2680,12 @@ "id": "82e381ec", "metadata": {}, "source": [ - "### 4.1 Setup and helpers\n" + "### 3.1 Setup and helpers\n" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 54, "id": "44e05e16", "metadata": {}, "outputs": [ @@ -2851,7 +2695,7 @@ "text": [ " % Total % Received % Xferd Average Speed Time Time Time Current\n", " Dload Upload Total Spent Left Speed\n", - "100 275k 100 275k 0 0 901k 0 --:--:-- --:--:-- --:--:-- 903k\n" + "100 275k 100 275k 0 0 923k 0 --:--:-- --:--:-- --:--:-- 927k\n" ] }, { @@ -2861,7 +2705,7 @@ "" ] }, - "execution_count": 29, + "execution_count": 54, "metadata": { "image/jpeg": { "height": 256, @@ -2880,13 +2724,13 @@ }, { "cell_type": "code", - "execution_count": 30, + "execution_count": 55, "id": "a2c1e1c2", "metadata": {}, "outputs": [], "source": [ "import base64\n", - "vision_model_id = \"meta-llama/Llama-3.2-11B-Vision-Instruct\"\n", + "vision_model_id = \"together/meta-llama/Llama-4-Scout-17B-16E-Instruct\"\n", "\n", "def encode_image(image_path):\n", " with open(image_path, \"rb\") as image_file:\n", @@ -2900,20 +2744,33 @@ "id": "7737cd41", "metadata": {}, "source": [ - "### 4.2 Using Llama Stack Inference API for multimodal inference" + "### 3.2 Using Llama Stack Inference API for multimodal inference" ] }, { "cell_type": "code", - "execution_count": 31, + "execution_count": 56, "id": "d7914894", "metadata": {}, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/chat/completions \"HTTP/1.1 200 OK\"\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "There are three llamas in the image. The llama in the middle is purple, the llama on the left is white, and the llama on the right is also white, but it is wearing a blue party hat. Therefore, there are two different colors of llama in the image: purple and white.\n" + "The image features three llamas, each with a distinct color. The colors of the llamas are as follows:\n", + "\n", + "* One llama is white.\n", + "* Another llama is purple.\n", + "* The third llama is also white.\n", + "\n", + "Therefore, there are two different colors present among the llamas: white and purple.\n" ] } ], @@ -2924,11 +2781,9 @@ " \"role\": \"user\",\n", " \"content\": [\n", " {\n", - " \"type\": \"image\",\n", - " \"image\": {\n", - " \"url\": {\n", - " \"uri\": encode_image(\"Llama_Repo.jpeg\")\n", - " }\n", + " \"type\": \"image_url\",\n", + " \"image_url\": {\n", + " \"url\": encode_image(\"Llama_Repo.jpeg\")\n", " }\n", " },\n", " {\n", @@ -2944,14 +2799,6 @@ "\n", "print(response.choices[0].message.content)" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f3352379", - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { @@ -2961,7 +2808,7 @@ "provenance": [] }, "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -2975,7 +2822,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.16" + "version": "3.12.12" } }, "nbformat": 4, diff --git a/docs/openapi_generator/run_openapi_generator.sh b/docs/openapi_generator/run_openapi_generator.sh index 45d00d6e7..6cffd42b0 100755 --- a/docs/openapi_generator/run_openapi_generator.sh +++ b/docs/openapi_generator/run_openapi_generator.sh @@ -30,3 +30,5 @@ fi stack_dir=$(dirname $(dirname $THIS_DIR)) PYTHONPATH=$PYTHONPATH:$stack_dir \ python -m docs.openapi_generator.generate $(dirname $THIS_DIR)/static + +cp $stack_dir/docs/static/stainless-llama-stack-spec.yaml $stack_dir/client-sdks/stainless/openapi.yml diff --git a/docs/quick_start.ipynb b/docs/quick_start.ipynb index 4ddde693f..0d5ad227c 100644 --- a/docs/quick_start.ipynb +++ b/docs/quick_start.ipynb @@ -126,17 +126,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "J2kGed0R5PSf", "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, - "collapsed": true, "id": "J2kGed0R5PSf", "outputId": "2478ea60-8d35-48a1-b011-f233831740c5" }, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\u001b[2mUsing Python 3.12.12 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/test\u001b[0m\n", + "\u001b[2mAudited \u001b[1m52 packages\u001b[0m \u001b[2min 1.56s\u001b[0m\u001b[0m\n", + "\u001b[2mUsing Python 3.12.12 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/test\u001b[0m\n", + "\u001b[2mAudited \u001b[1m3 packages\u001b[0m \u001b[2min 122ms\u001b[0m\u001b[0m\n", + "\u001b[2mUsing Python 3.12.12 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/test\u001b[0m\n", + "\u001b[2mAudited \u001b[1m3 packages\u001b[0m \u001b[2min 197ms\u001b[0m\u001b[0m\n", + "\u001b[2mUsing Python 3.12.12 environment at: /opt/homebrew/Caskroom/miniconda/base/envs/test\u001b[0m\n", + "\u001b[2mAudited \u001b[1m1 package\u001b[0m \u001b[2min 11ms\u001b[0m\u001b[0m\n" + ] + } + ], "source": [ "import os\n", "import subprocess\n", @@ -150,7 +164,7 @@ "def run_llama_stack_server_background():\n", " log_file = open(\"llama_stack_server.log\", \"w\")\n", " process = subprocess.Popen(\n", - " f\"OLLAMA_URL=http://localhost:11434 uv run --with llama-stack llama stack run starter\n", + " f\"OLLAMA_URL=http://localhost:11434 uv run --with llama-stack llama stack run starter\",\n", " shell=True,\n", " stdout=log_file,\n", " stderr=log_file,\n", @@ -200,7 +214,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 2, "id": "f779283d", "metadata": {}, "outputs": [ @@ -208,8 +222,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "Starting Llama Stack server with PID: 787100\n", - "Waiting for server to start\n", + "Starting Llama Stack server with PID: 20778\n", + "Waiting for server to start........\n", "Server is ready!\n" ] } @@ -229,65 +243,84 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 3, "id": "7da71011", "metadata": {}, "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:httpx:HTTP Request: GET http://0.0.0.0:8321/v1/models \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/files \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/vector_stores \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/conversations \"HTTP/1.1 200 OK\"\n", + "INFO:httpx:HTTP Request: POST http://0.0.0.0:8321/v1/responses \"HTTP/1.1 200 OK\"\n" + ] + }, { "name": "stdout", "output_type": "stream", "text": [ - "rag_tool> Ingesting document: https://www.paulgraham.com/greatwork.html\n", "prompt> How do you do great work?\n", - "\u001b[33minference> \u001b[0m\u001b[33m[k\u001b[0m\u001b[33mnowledge\u001b[0m\u001b[33m_search\u001b[0m\u001b[33m(query\u001b[0m\u001b[33m=\"\u001b[0m\u001b[33mWhat\u001b[0m\u001b[33m is\u001b[0m\u001b[33m the\u001b[0m\u001b[33m key\u001b[0m\u001b[33m to\u001b[0m\u001b[33m doing\u001b[0m\u001b[33m great\u001b[0m\u001b[33m work\u001b[0m\u001b[33m\")]\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[32mtool_execution> Tool:knowledge_search Args:{'query': 'What is the key to doing great work'}\u001b[0m\n", - "\u001b[32mtool_execution> Tool:knowledge_search Response:[TextContentItem(text='knowledge_search tool found 5 chunks:\\nBEGIN of knowledge_search tool results.\\n', type='text'), TextContentItem(text=\"Result 1:\\nDocument_id:docum\\nContent: work. Doing great work means doing something important\\nso well that you expand people's ideas of what's possible. But\\nthere's no threshold for importance. It's a matter of degree, and\\noften hard to judge at the time anyway.\\n\", type='text'), TextContentItem(text=\"Result 2:\\nDocument_id:docum\\nContent: work. Doing great work means doing something important\\nso well that you expand people's ideas of what's possible. But\\nthere's no threshold for importance. It's a matter of degree, and\\noften hard to judge at the time anyway.\\n\", type='text'), TextContentItem(text=\"Result 3:\\nDocument_id:docum\\nContent: work. Doing great work means doing something important\\nso well that you expand people's ideas of what's possible. But\\nthere's no threshold for importance. It's a matter of degree, and\\noften hard to judge at the time anyway.\\n\", type='text'), TextContentItem(text=\"Result 4:\\nDocument_id:docum\\nContent: work. Doing great work means doing something important\\nso well that you expand people's ideas of what's possible. But\\nthere's no threshold for importance. It's a matter of degree, and\\noften hard to judge at the time anyway.\\n\", type='text'), TextContentItem(text=\"Result 5:\\nDocument_id:docum\\nContent: work. Doing great work means doing something important\\nso well that you expand people's ideas of what's possible. But\\nthere's no threshold for importance. It's a matter of degree, and\\noften hard to judge at the time anyway.\\n\", type='text'), TextContentItem(text='END of knowledge_search tool results.\\n', type='text'), TextContentItem(text='The above results were retrieved to help answer the user\\'s query: \"What is the key to doing great work\". Use them as supporting information only in answering this query.\\n', type='text')]\u001b[0m\n", - "\u001b[33minference> \u001b[0m\u001b[33mDoing\u001b[0m\u001b[33m great\u001b[0m\u001b[33m work\u001b[0m\u001b[33m means\u001b[0m\u001b[33m doing\u001b[0m\u001b[33m something\u001b[0m\u001b[33m important\u001b[0m\u001b[33m so\u001b[0m\u001b[33m well\u001b[0m\u001b[33m that\u001b[0m\u001b[33m you\u001b[0m\u001b[33m expand\u001b[0m\u001b[33m people\u001b[0m\u001b[33m's\u001b[0m\u001b[33m ideas\u001b[0m\u001b[33m of\u001b[0m\u001b[33m what\u001b[0m\u001b[33m's\u001b[0m\u001b[33m possible\u001b[0m\u001b[33m.\u001b[0m\u001b[33m However\u001b[0m\u001b[33m,\u001b[0m\u001b[33m there\u001b[0m\u001b[33m's\u001b[0m\u001b[33m no\u001b[0m\u001b[33m threshold\u001b[0m\u001b[33m for\u001b[0m\u001b[33m importance\u001b[0m\u001b[33m,\u001b[0m\u001b[33m and\u001b[0m\u001b[33m it\u001b[0m\u001b[33m's\u001b[0m\u001b[33m often\u001b[0m\u001b[33m hard\u001b[0m\u001b[33m to\u001b[0m\u001b[33m judge\u001b[0m\u001b[33m at\u001b[0m\u001b[33m the\u001b[0m\u001b[33m time\u001b[0m\u001b[33m anyway\u001b[0m\u001b[33m.\u001b[0m\u001b[33m Great\u001b[0m\u001b[33m work\u001b[0m\u001b[33m is\u001b[0m\u001b[33m a\u001b[0m\u001b[33m matter\u001b[0m\u001b[33m of\u001b[0m\u001b[33m degree\u001b[0m\u001b[33m,\u001b[0m\u001b[33m and\u001b[0m\u001b[33m it\u001b[0m\u001b[33m can\u001b[0m\u001b[33m be\u001b[0m\u001b[33m difficult\u001b[0m\u001b[33m to\u001b[0m\u001b[33m determine\u001b[0m\u001b[33m whether\u001b[0m\u001b[33m someone\u001b[0m\u001b[33m has\u001b[0m\u001b[33m done\u001b[0m\u001b[33m great\u001b[0m\u001b[33m work\u001b[0m\u001b[33m until\u001b[0m\u001b[33m after\u001b[0m\u001b[33m the\u001b[0m\u001b[33m fact\u001b[0m\u001b[33m.\u001b[0m\u001b[97m\u001b[0m\n", - "\u001b[30m\u001b[0m" + "🤔 Doing great work involves a combination of skills, habits, and mindsets. Here are some key principles:\n", + "\n", + "1. **Set Clear Goals**: Start with a clear vision of what you want to achieve. Define specific, measurable, achievable, relevant, and time-bound (SMART) goals.\n", + "\n", + "2. **Plan and Prioritize**: Break your goals into smaller, manageable tasks. Prioritize these tasks based on their importance and urgency.\n", + "\n", + "3. **Focus on Quality**: Aim for high-quality outcomes rather than just finishing tasks. Pay attention to detail, and ensure your work meets or exceeds standards.\n", + "\n", + "4. **Stay Organized**: Keep your workspace, both physical and digital, organized to help you stay focused and efficient.\n", + "\n", + "5. **Manage Your Time**: Use time management techniques such as the Pomodoro Technique, time blocking, or the Eisenhower Box to maximize productivity.\n", + "\n", + "6. **Seek Feedback and Learn**: Regularly seek feedback from peers, mentors, or supervisors. Use constructive criticism to improve continuously.\n", + "\n", + "7. **Innovate and Improve**: Look for ways to improve processes or introduce new ideas. Be open to change and willing to adapt.\n", + "\n", + "8. **Stay Motivated and Persistent**: Keep your end goals in mind to stay motivated. Overcome setbacks with resilience and persistence.\n", + "\n", + "9. **Balance and Rest**: Ensure you maintain a healthy work-life balance. Take breaks and manage stress to sustain long-term productivity.\n", + "\n", + "10. **Reflect and Adjust**: Regularly assess your progress and adjust your strategies as needed. Reflect on what works well and what doesn't.\n", + "\n", + "By incorporating these elements, you can consistently produce high-quality work and achieve excellence in your endeavors.\n" ] } ], "source": [ "from llama_stack_client import Agent, AgentEventLogger, RAGDocument, LlamaStackClient\n", + "import requests\n", "\n", - "vector_db_id = \"my_demo_vector_db\"\n", + "vector_store_id = \"my_demo_vector_db\"\n", "client = LlamaStackClient(base_url=\"http://0.0.0.0:8321\")\n", "\n", "models = client.models.list()\n", "\n", "# Select the first ollama and first ollama's embedding model\n", "model_id = next(m for m in models if m.model_type == \"llm\" and m.provider_id == \"ollama\").identifier\n", - "embedding_model = next(m for m in models if m.model_type == \"embedding\" and m.provider_id == \"ollama\")\n", - "embedding_model_id = embedding_model.identifier\n", - "embedding_dimension = embedding_model.metadata[\"embedding_dimension\"]\n", "\n", - "_ = client.vector_dbs.register(\n", - " vector_db_id=vector_db_id,\n", - " embedding_model=embedding_model_id,\n", - " embedding_dimension=embedding_dimension,\n", - " provider_id=\"faiss\",\n", - ")\n", + "\n", "source = \"https://www.paulgraham.com/greatwork.html\"\n", - "print(\"rag_tool> Ingesting document:\", source)\n", - "document = RAGDocument(\n", - " document_id=\"document_1\",\n", - " content=source,\n", - " mime_type=\"text/html\",\n", - " metadata={},\n", + "response = requests.get(source)\n", + "file = client.files.create(\n", + " file=response.content,\n", + " purpose='assistants'\n", ")\n", - "client.tool_runtime.rag_tool.insert(\n", - " documents=[document],\n", - " vector_db_id=vector_db_id,\n", - " chunk_size_in_tokens=50,\n", + "vector_store = client.vector_stores.create(\n", + " name=vector_store_id,\n", + " file_ids=[file.id],\n", ")\n", + "\n", "agent = Agent(\n", " client,\n", " model=model_id,\n", " instructions=\"You are a helpful assistant\",\n", " tools=[\n", " {\n", - " \"name\": \"builtin::rag/knowledge_search\",\n", - " \"args\": {\"vector_db_ids\": [vector_db_id]},\n", + " \"type\": \"file_search\",\n", + " \"vector_store_ids\": [vector_store_id],\n", " }\n", " ],\n", ")\n", @@ -302,7 +335,7 @@ ")\n", "\n", "for log in AgentEventLogger().log(response):\n", - " log.print()" + " print(log, end=\"\")" ] }, { @@ -344,7 +377,7 @@ "provenance": [] }, "kernelspec": { - "display_name": "Python 3", + "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, @@ -358,7 +391,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.6" + "version": "3.12.12" } }, "nbformat": 4, diff --git a/docs/static/deprecated-llama-stack-spec.html b/docs/static/deprecated-llama-stack-spec.html index 60a8b9fbd..d920317cf 100644 --- a/docs/static/deprecated-llama-stack-spec.html +++ b/docs/static/deprecated-llama-stack-spec.html @@ -5547,7 +5547,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -5798,7 +5798,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -9024,6 +9024,10 @@ "$ref": "#/components/schemas/OpenAIResponseUsage", "description": "(Optional) Token usage information for the response" }, + "instructions": { + "type": "string", + "description": "(Optional) System message inserted into the model's context" + }, "input": { "type": "array", "items": { @@ -9901,6 +9905,10 @@ "usage": { "$ref": "#/components/schemas/OpenAIResponseUsage", "description": "(Optional) Token usage information for the response" + }, + "instructions": { + "type": "string", + "description": "(Optional) System message inserted into the model's context" } }, "additionalProperties": false, diff --git a/docs/static/deprecated-llama-stack-spec.yaml b/docs/static/deprecated-llama-stack-spec.yaml index aaa6cd413..66b2caeca 100644 --- a/docs/static/deprecated-llama-stack-spec.yaml +++ b/docs/static/deprecated-llama-stack-spec.yaml @@ -4114,7 +4114,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -4303,7 +4303,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -6734,6 +6734,10 @@ components: $ref: '#/components/schemas/OpenAIResponseUsage' description: >- (Optional) Token usage information for the response + instructions: + type: string + description: >- + (Optional) System message inserted into the model's context input: type: array items: @@ -7403,6 +7407,10 @@ components: $ref: '#/components/schemas/OpenAIResponseUsage' description: >- (Optional) Token usage information for the response + instructions: + type: string + description: >- + (Optional) System message inserted into the model's context additionalProperties: false required: - created_at diff --git a/docs/static/experimental-llama-stack-spec.html b/docs/static/experimental-llama-stack-spec.html index 7d572f89f..ab474180e 100644 --- a/docs/static/experimental-llama-stack-spec.html +++ b/docs/static/experimental-llama-stack-spec.html @@ -1850,7 +1850,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -3983,7 +3983,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", diff --git a/docs/static/experimental-llama-stack-spec.yaml b/docs/static/experimental-llama-stack-spec.yaml index fee20814c..dd9e43cc5 100644 --- a/docs/static/experimental-llama-stack-spec.yaml +++ b/docs/static/experimental-llama-stack-spec.yaml @@ -1320,7 +1320,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -2927,7 +2927,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark diff --git a/docs/static/llama-stack-spec.html b/docs/static/llama-stack-spec.html index 413e4f23e..61deaec1e 100644 --- a/docs/static/llama-stack-spec.html +++ b/docs/static/llama-stack-spec.html @@ -6800,7 +6800,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -7600,6 +7600,10 @@ "$ref": "#/components/schemas/OpenAIResponseUsage", "description": "(Optional) Token usage information for the response" }, + "instructions": { + "type": "string", + "description": "(Optional) System message inserted into the model's context" + }, "input": { "type": "array", "items": { @@ -8148,6 +8152,10 @@ "usage": { "$ref": "#/components/schemas/OpenAIResponseUsage", "description": "(Optional) Token usage information for the response" + }, + "instructions": { + "type": "string", + "description": "(Optional) System message inserted into the model's context" } }, "additionalProperties": false, @@ -10197,7 +10205,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -10679,7 +10687,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -11732,7 +11740,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", diff --git a/docs/static/llama-stack-spec.yaml b/docs/static/llama-stack-spec.yaml index 93e51de6a..c6197b36f 100644 --- a/docs/static/llama-stack-spec.yaml +++ b/docs/static/llama-stack-spec.yaml @@ -5227,7 +5227,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -5815,6 +5815,10 @@ components: $ref: '#/components/schemas/OpenAIResponseUsage' description: >- (Optional) Token usage information for the response + instructions: + type: string + description: >- + (Optional) System message inserted into the model's context input: type: array items: @@ -6218,6 +6222,10 @@ components: $ref: '#/components/schemas/OpenAIResponseUsage' description: >- (Optional) Token usage information for the response + instructions: + type: string + description: >- + (Optional) System message inserted into the model's context additionalProperties: false required: - created_at @@ -7911,7 +7919,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -8219,7 +8227,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -8982,7 +8990,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark diff --git a/docs/static/stainless-llama-stack-spec.html b/docs/static/stainless-llama-stack-spec.html index 858f20725..38122ebc0 100644 --- a/docs/static/stainless-llama-stack-spec.html +++ b/docs/static/stainless-llama-stack-spec.html @@ -8472,7 +8472,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -9272,6 +9272,10 @@ "$ref": "#/components/schemas/OpenAIResponseUsage", "description": "(Optional) Token usage information for the response" }, + "instructions": { + "type": "string", + "description": "(Optional) System message inserted into the model's context" + }, "input": { "type": "array", "items": { @@ -9820,6 +9824,10 @@ "usage": { "$ref": "#/components/schemas/OpenAIResponseUsage", "description": "(Optional) Token usage information for the response" + }, + "instructions": { + "type": "string", + "description": "(Optional) System message inserted into the model's context" } }, "additionalProperties": false, @@ -11869,7 +11877,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -12351,7 +12359,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -13404,7 +13412,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -14951,7 +14959,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", @@ -16696,7 +16704,7 @@ "enum": [ "model", "shield", - "vector_db", + "vector_store", "dataset", "scoring_function", "benchmark", diff --git a/docs/static/stainless-llama-stack-spec.yaml b/docs/static/stainless-llama-stack-spec.yaml index 886549dbc..93049a14a 100644 --- a/docs/static/stainless-llama-stack-spec.yaml +++ b/docs/static/stainless-llama-stack-spec.yaml @@ -6440,7 +6440,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -7028,6 +7028,10 @@ components: $ref: '#/components/schemas/OpenAIResponseUsage' description: >- (Optional) Token usage information for the response + instructions: + type: string + description: >- + (Optional) System message inserted into the model's context input: type: array items: @@ -7431,6 +7435,10 @@ components: $ref: '#/components/schemas/OpenAIResponseUsage' description: >- (Optional) Token usage information for the response + instructions: + type: string + description: >- + (Optional) System message inserted into the model's context additionalProperties: false required: - created_at @@ -9124,7 +9132,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -9432,7 +9440,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -10195,7 +10203,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -11317,7 +11325,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark @@ -12644,7 +12652,7 @@ components: enum: - model - shield - - vector_db + - vector_store - dataset - scoring_function - benchmark diff --git a/llama_stack/apis/agents/openai_responses.py b/llama_stack/apis/agents/openai_responses.py index 25dc89a6b..821d6a8af 100644 --- a/llama_stack/apis/agents/openai_responses.py +++ b/llama_stack/apis/agents/openai_responses.py @@ -545,6 +545,7 @@ class OpenAIResponseObject(BaseModel): :param tools: (Optional) An array of tools the model may call while generating a response. :param truncation: (Optional) Truncation strategy applied to the response :param usage: (Optional) Token usage information for the response + :param instructions: (Optional) System message inserted into the model's context """ created_at: int @@ -564,6 +565,7 @@ class OpenAIResponseObject(BaseModel): tools: list[OpenAIResponseTool] | None = None truncation: str | None = None usage: OpenAIResponseUsage | None = None + instructions: str | None = None @json_schema_type diff --git a/llama_stack/apis/datatypes.py b/llama_stack/apis/datatypes.py index 8fbf21f3e..948ec615f 100644 --- a/llama_stack/apis/datatypes.py +++ b/llama_stack/apis/datatypes.py @@ -121,6 +121,7 @@ class Api(Enum, metaclass=DynamicApiMeta): models = "models" shields = "shields" + vector_stores = "vector_stores" # only used for routing table datasets = "datasets" scoring_functions = "scoring_functions" benchmarks = "benchmarks" diff --git a/llama_stack/apis/resource.py b/llama_stack/apis/resource.py index 7c4130f7d..dafdb28b0 100644 --- a/llama_stack/apis/resource.py +++ b/llama_stack/apis/resource.py @@ -13,7 +13,7 @@ from pydantic import BaseModel, Field class ResourceType(StrEnum): model = "model" shield = "shield" - vector_db = "vector_db" + vector_store = "vector_store" dataset = "dataset" scoring_function = "scoring_function" benchmark = "benchmark" @@ -34,4 +34,4 @@ class Resource(BaseModel): provider_id: str = Field(description="ID of the provider that owns this resource") - type: ResourceType = Field(description="Type of resource (e.g. 'model', 'shield', 'vector_db', etc.)") + type: ResourceType = Field(description="Type of resource (e.g. 'model', 'shield', 'vector_store', etc.)") diff --git a/llama_stack/apis/vector_io/vector_io.py b/llama_stack/apis/vector_io/vector_io.py index a309c47f9..49e4df039 100644 --- a/llama_stack/apis/vector_io/vector_io.py +++ b/llama_stack/apis/vector_io/vector_io.py @@ -15,7 +15,7 @@ from fastapi import Body from pydantic import BaseModel, Field from llama_stack.apis.inference import InterleavedContent -from llama_stack.apis.vector_dbs import VectorDB +from llama_stack.apis.vector_stores import VectorStore from llama_stack.apis.version import LLAMA_STACK_API_V1 from llama_stack.providers.utils.telemetry.trace_protocol import trace_protocol from llama_stack.providers.utils.vector_io.vector_utils import generate_chunk_id @@ -140,6 +140,7 @@ class VectorStoreFileCounts(BaseModel): total: int +# TODO: rename this as OpenAIVectorStore @json_schema_type class VectorStoreObject(BaseModel): """OpenAI Vector Store object. @@ -517,17 +518,18 @@ class OpenAICreateVectorStoreFileBatchRequestWithExtraBody(BaseModel, extra="all chunking_strategy: VectorStoreChunkingStrategy | None = None -class VectorDBStore(Protocol): - def get_vector_db(self, vector_db_id: str) -> VectorDB | None: ... +class VectorStoreTable(Protocol): + def get_vector_store(self, vector_store_id: str) -> VectorStore | None: ... @runtime_checkable @trace_protocol class VectorIO(Protocol): - vector_db_store: VectorDBStore | None = None + vector_store_table: VectorStoreTable | None = None # this will just block now until chunks are inserted, but it should # probably return a Job instance which can be polled for completion + # TODO: rename vector_db_id to vector_store_id once Stainless is working @webmethod(route="/vector-io/insert", method="POST", level=LLAMA_STACK_API_V1) async def insert_chunks( self, @@ -546,6 +548,7 @@ class VectorIO(Protocol): """ ... + # TODO: rename vector_db_id to vector_store_id once Stainless is working @webmethod(route="/vector-io/query", method="POST", level=LLAMA_STACK_API_V1) async def query_chunks( self, diff --git a/llama_stack/apis/vector_stores/__init__.py b/llama_stack/apis/vector_stores/__init__.py new file mode 100644 index 000000000..8fc34058a --- /dev/null +++ b/llama_stack/apis/vector_stores/__init__.py @@ -0,0 +1,7 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +from .vector_stores import * diff --git a/llama_stack/apis/vector_dbs/vector_dbs.py b/llama_stack/apis/vector_stores/vector_stores.py similarity index 56% rename from llama_stack/apis/vector_dbs/vector_dbs.py rename to llama_stack/apis/vector_stores/vector_stores.py index 53bf181e9..524624028 100644 --- a/llama_stack/apis/vector_dbs/vector_dbs.py +++ b/llama_stack/apis/vector_stores/vector_stores.py @@ -9,53 +9,43 @@ from typing import Literal from pydantic import BaseModel from llama_stack.apis.resource import Resource, ResourceType -from llama_stack.schema_utils import json_schema_type -@json_schema_type -class VectorDB(Resource): +# Internal resource type for storing the vector store routing and other information +class VectorStore(Resource): """Vector database resource for storing and querying vector embeddings. - :param type: Type of resource, always 'vector_db' for vector databases + :param type: Type of resource, always 'vector_store' for vector stores :param embedding_model: Name of the embedding model to use for vector generation :param embedding_dimension: Dimension of the embedding vectors """ - type: Literal[ResourceType.vector_db] = ResourceType.vector_db + type: Literal[ResourceType.vector_store] = ResourceType.vector_store embedding_model: str embedding_dimension: int - vector_db_name: str | None = None + vector_store_name: str | None = None @property - def vector_db_id(self) -> str: + def vector_store_id(self) -> str: return self.identifier @property - def provider_vector_db_id(self) -> str | None: + def provider_vector_store_id(self) -> str | None: return self.provider_resource_id -class VectorDBInput(BaseModel): +class VectorStoreInput(BaseModel): """Input parameters for creating or configuring a vector database. - :param vector_db_id: Unique identifier for the vector database + :param vector_store_id: Unique identifier for the vector store :param embedding_model: Name of the embedding model to use for vector generation :param embedding_dimension: Dimension of the embedding vectors - :param provider_vector_db_id: (Optional) Provider-specific identifier for the vector database + :param provider_vector_store_id: (Optional) Provider-specific identifier for the vector store """ - vector_db_id: str + vector_store_id: str embedding_model: str embedding_dimension: int provider_id: str | None = None - provider_vector_db_id: str | None = None - - -class ListVectorDBsResponse(BaseModel): - """Response from listing vector databases. - - :param data: List of vector databases - """ - - data: list[VectorDB] + provider_vector_store_id: str | None = None diff --git a/llama_stack/cli/llama.py b/llama_stack/cli/llama.py index 5ff15d8d7..aa8893bc0 100644 --- a/llama_stack/cli/llama.py +++ b/llama_stack/cli/llama.py @@ -6,6 +6,8 @@ import argparse +from llama_stack.log import setup_logging + from .stack import StackParser from .stack.utils import print_subcommand_description @@ -42,6 +44,9 @@ class LlamaCLIParser: def main(): + # Initialize logging from environment variables before any other operations + setup_logging() + parser = LlamaCLIParser() args = parser.parse_args() parser.run(args) diff --git a/llama_stack/cli/stack/_build.py b/llama_stack/cli/stack/_build.py deleted file mode 100644 index 471d5cb66..000000000 --- a/llama_stack/cli/stack/_build.py +++ /dev/null @@ -1,490 +0,0 @@ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under the terms described in the LICENSE file in -# the root directory of this source tree. - -import argparse -import importlib.resources -import json -import os -import shutil -import sys -import textwrap -from functools import lru_cache -from importlib.abc import Traversable -from pathlib import Path - -import yaml -from prompt_toolkit import prompt -from prompt_toolkit.completion import WordCompleter -from prompt_toolkit.validation import Validator -from termcolor import colored, cprint - -from llama_stack.cli.stack.utils import ImageType -from llama_stack.cli.table import print_table -from llama_stack.core.build import ( - SERVER_DEPENDENCIES, - build_image, - get_provider_dependencies, -) -from llama_stack.core.configure import parse_and_maybe_upgrade_config -from llama_stack.core.datatypes import ( - BuildConfig, - BuildProvider, - DistributionSpec, - Provider, - StackRunConfig, -) -from llama_stack.core.distribution import get_provider_registry -from llama_stack.core.external import load_external_apis -from llama_stack.core.resolver import InvalidProviderError -from llama_stack.core.stack import replace_env_vars -from llama_stack.core.utils.config_dirs import DISTRIBS_BASE_DIR, EXTERNAL_PROVIDERS_DIR -from llama_stack.core.utils.dynamic import instantiate_class_type -from llama_stack.core.utils.exec import formulate_run_args, run_command -from llama_stack.core.utils.image_types import LlamaStackImageType -from llama_stack.providers.datatypes import Api -from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig - -DISTRIBS_PATH = Path(__file__).parent.parent.parent / "distributions" - - -@lru_cache -def available_distros_specs() -> dict[str, BuildConfig]: - import yaml - - distro_specs = {} - for p in DISTRIBS_PATH.rglob("*build.yaml"): - distro_name = p.parent.name - with open(p) as f: - build_config = BuildConfig(**yaml.safe_load(f)) - distro_specs[distro_name] = build_config - return distro_specs - - -def run_stack_build_command(args: argparse.Namespace) -> None: - if args.list_distros: - return _run_distro_list_cmd() - - if args.image_type == ImageType.VENV.value: - current_venv = os.environ.get("VIRTUAL_ENV") - image_name = args.image_name or current_venv - else: - image_name = args.image_name - - if args.template: - cprint( - "The --template argument is deprecated. Please use --distro instead.", - color="red", - file=sys.stderr, - ) - distro_name = args.template - else: - distro_name = args.distribution - - if distro_name: - available_distros = available_distros_specs() - if distro_name not in available_distros: - cprint( - f"Could not find distribution {distro_name}. Please run `llama stack build --list-distros` to check out the available distributions", - color="red", - file=sys.stderr, - ) - sys.exit(1) - build_config = available_distros[distro_name] - if args.image_type: - build_config.image_type = args.image_type - else: - cprint( - f"Please specify a image-type ({' | '.join(e.value for e in ImageType)}) for {distro_name}", - color="red", - file=sys.stderr, - ) - sys.exit(1) - elif args.providers: - provider_list: dict[str, list[BuildProvider]] = dict() - for api_provider in args.providers.split(","): - if "=" not in api_provider: - cprint( - "Could not parse `--providers`. Please ensure the list is in the format api1=provider1,api2=provider2", - color="red", - file=sys.stderr, - ) - sys.exit(1) - api, provider_type = api_provider.split("=") - providers_for_api = get_provider_registry().get(Api(api), None) - if providers_for_api is None: - cprint( - f"{api} is not a valid API.", - color="red", - file=sys.stderr, - ) - sys.exit(1) - if provider_type in providers_for_api: - provider = BuildProvider( - provider_type=provider_type, - module=None, - ) - provider_list.setdefault(api, []).append(provider) - else: - cprint( - f"{provider} is not a valid provider for the {api} API.", - color="red", - file=sys.stderr, - ) - sys.exit(1) - distribution_spec = DistributionSpec( - providers=provider_list, - description=",".join(args.providers), - ) - if not args.image_type: - cprint( - f"Please specify a image-type (container | venv) for {args.template}", - color="red", - file=sys.stderr, - ) - sys.exit(1) - - build_config = BuildConfig(image_type=args.image_type, distribution_spec=distribution_spec) - elif not args.config and not distro_name: - name = prompt( - "> Enter a name for your Llama Stack (e.g. my-local-stack): ", - validator=Validator.from_callable( - lambda x: len(x) > 0, - error_message="Name cannot be empty, please enter a name", - ), - ) - - image_type = prompt( - "> Enter the image type you want your Llama Stack to be built as (use to see options): ", - completer=WordCompleter([e.value for e in ImageType]), - complete_while_typing=True, - validator=Validator.from_callable( - lambda x: x in [e.value for e in ImageType], - error_message="Invalid image type. Use to see options", - ), - ) - - image_name = f"llamastack-{name}" - - cprint( - textwrap.dedent( - """ - Llama Stack is composed of several APIs working together. Let's select - the provider types (implementations) you want to use for these APIs. - """, - ), - color="green", - file=sys.stderr, - ) - - cprint("Tip: use to see options for the providers.\n", color="green", file=sys.stderr) - - providers: dict[str, list[BuildProvider]] = dict() - for api, providers_for_api in get_provider_registry().items(): - available_providers = [x for x in providers_for_api.keys() if x not in ("remote", "remote::sample")] - if not available_providers: - continue - api_provider = prompt( - f"> Enter provider for API {api.value}: ", - completer=WordCompleter(available_providers), - complete_while_typing=True, - validator=Validator.from_callable( - lambda x: x in available_providers, # noqa: B023 - see https://github.com/astral-sh/ruff/issues/7847 - error_message="Invalid provider, use to see options", - ), - ) - - string_providers = api_provider.split(" ") - - for provider in string_providers: - providers.setdefault(api.value, []).append(BuildProvider(provider_type=provider)) - - description = prompt( - "\n > (Optional) Enter a short description for your Llama Stack: ", - default="", - ) - - distribution_spec = DistributionSpec( - providers=providers, - description=description, - ) - - build_config = BuildConfig(image_type=image_type, distribution_spec=distribution_spec) - else: - with open(args.config) as f: - try: - contents = yaml.safe_load(f) - contents = replace_env_vars(contents) - build_config = BuildConfig(**contents) - if args.image_type: - build_config.image_type = args.image_type - except Exception as e: - cprint( - f"Could not parse config file {args.config}: {e}", - color="red", - file=sys.stderr, - ) - sys.exit(1) - - if args.print_deps_only: - print(f"# Dependencies for {distro_name or args.config or image_name}") - normal_deps, special_deps, external_provider_dependencies = get_provider_dependencies(build_config) - normal_deps += SERVER_DEPENDENCIES - print(f"uv pip install {' '.join(normal_deps)}") - for special_dep in special_deps: - print(f"uv pip install {special_dep}") - for external_dep in external_provider_dependencies: - print(f"uv pip install {external_dep}") - return - - try: - run_config = _run_stack_build_command_from_build_config( - build_config, - image_name=image_name, - config_path=args.config, - distro_name=distro_name, - ) - - except (Exception, RuntimeError) as exc: - import traceback - - cprint( - f"Error building stack: {exc}", - color="red", - file=sys.stderr, - ) - cprint("Stack trace:", color="red", file=sys.stderr) - traceback.print_exc() - sys.exit(1) - - if run_config is None: - cprint( - "Run config path is empty", - color="red", - file=sys.stderr, - ) - sys.exit(1) - - if args.run: - config_dict = yaml.safe_load(run_config.read_text()) - config = parse_and_maybe_upgrade_config(config_dict) - if config.external_providers_dir and not config.external_providers_dir.exists(): - config.external_providers_dir.mkdir(exist_ok=True) - run_args = formulate_run_args(args.image_type, image_name or config.image_name) - run_args.extend([str(os.getenv("LLAMA_STACK_PORT", 8321)), "--config", str(run_config)]) - run_command(run_args) - - -def _generate_run_config( - build_config: BuildConfig, - build_dir: Path, - image_name: str, -) -> Path: - """ - Generate a run.yaml template file for user to edit from a build.yaml file - """ - apis = list(build_config.distribution_spec.providers.keys()) - run_config = StackRunConfig( - container_image=(image_name if build_config.image_type == LlamaStackImageType.CONTAINER.value else None), - image_name=image_name, - apis=apis, - providers={}, - external_providers_dir=build_config.external_providers_dir - if build_config.external_providers_dir - else EXTERNAL_PROVIDERS_DIR, - ) - if not run_config.inference_store: - run_config.inference_store = SqliteSqlStoreConfig( - **SqliteSqlStoreConfig.sample_run_config( - __distro_dir__=(DISTRIBS_BASE_DIR / image_name).as_posix(), db_name="inference_store.db" - ) - ) - # build providers dict - provider_registry = get_provider_registry(build_config) - for api in apis: - run_config.providers[api] = [] - providers = build_config.distribution_spec.providers[api] - - for provider in providers: - pid = provider.provider_type.split("::")[-1] - - p = provider_registry[Api(api)][provider.provider_type] - if p.deprecation_error: - raise InvalidProviderError(p.deprecation_error) - - try: - config_type = instantiate_class_type(provider_registry[Api(api)][provider.provider_type].config_class) - except (ModuleNotFoundError, ValueError) as exc: - # HACK ALERT: - # This code executes after building is done, the import cannot work since the - # package is either available in the venv or container - not available on the host. - # TODO: use a "is_external" flag in ProviderSpec to check if the provider is - # external - cprint( - f"Failed to import provider {provider.provider_type} for API {api} - assuming it's external, skipping: {exc}", - color="yellow", - file=sys.stderr, - ) - # Set config_type to None to avoid UnboundLocalError - config_type = None - - if config_type is not None and hasattr(config_type, "sample_run_config"): - config = config_type.sample_run_config(__distro_dir__=f"~/.llama/distributions/{image_name}") - else: - config = {} - - p_spec = Provider( - provider_id=pid, - provider_type=provider.provider_type, - config=config, - module=provider.module, - ) - run_config.providers[api].append(p_spec) - - run_config_file = build_dir / f"{image_name}-run.yaml" - - with open(run_config_file, "w") as f: - to_write = json.loads(run_config.model_dump_json()) - f.write(yaml.dump(to_write, sort_keys=False)) - - # Only print this message for non-container builds since it will be displayed before the - # container is built - # For non-container builds, the run.yaml is generated at the very end of the build process so it - # makes sense to display this message - if build_config.image_type != LlamaStackImageType.CONTAINER.value: - cprint(f"You can now run your stack with `llama stack run {run_config_file}`", color="green", file=sys.stderr) - return run_config_file - - -def _run_stack_build_command_from_build_config( - build_config: BuildConfig, - image_name: str | None = None, - distro_name: str | None = None, - config_path: str | None = None, -) -> Path | Traversable: - image_name = image_name or build_config.image_name - if build_config.image_type == LlamaStackImageType.CONTAINER.value: - if distro_name: - image_name = f"distribution-{distro_name}" - else: - if not image_name: - raise ValueError("Please specify an image name when building a container image without a template") - else: - if not image_name and os.environ.get("UV_SYSTEM_PYTHON"): - image_name = "__system__" - if not image_name: - raise ValueError("Please specify an image name when building a venv image") - - # At this point, image_name should be guaranteed to be a string - if image_name is None: - raise ValueError("image_name should not be None after validation") - - if distro_name: - build_dir = DISTRIBS_BASE_DIR / distro_name - build_file_path = build_dir / f"{distro_name}-build.yaml" - else: - if image_name is None: - raise ValueError("image_name cannot be None") - build_dir = DISTRIBS_BASE_DIR / image_name - build_file_path = build_dir / f"{image_name}-build.yaml" - - os.makedirs(build_dir, exist_ok=True) - run_config_file = None - # Generate the run.yaml so it can be included in the container image with the proper entrypoint - # Only do this if we're building a container image and we're not using a template - if build_config.image_type == LlamaStackImageType.CONTAINER.value and not distro_name and config_path: - cprint("Generating run.yaml file", color="yellow", file=sys.stderr) - run_config_file = _generate_run_config(build_config, build_dir, image_name) - - with open(build_file_path, "w") as f: - to_write = json.loads(build_config.model_dump_json(exclude_none=True)) - f.write(yaml.dump(to_write, sort_keys=False)) - - # We first install the external APIs so that the build process can use them and discover the - # providers dependencies - if build_config.external_apis_dir: - cprint("Installing external APIs", color="yellow", file=sys.stderr) - external_apis = load_external_apis(build_config) - if external_apis: - # install the external APIs - packages = [] - for _, api_spec in external_apis.items(): - if api_spec.pip_packages: - packages.extend(api_spec.pip_packages) - cprint( - f"Installing {api_spec.name} with pip packages {api_spec.pip_packages}", - color="yellow", - file=sys.stderr, - ) - return_code = run_command(["uv", "pip", "install", *packages]) - if return_code != 0: - packages_str = ", ".join(packages) - raise RuntimeError( - f"Failed to install external APIs packages: {packages_str} (return code: {return_code})" - ) - - return_code = build_image( - build_config, - image_name, - distro_or_config=distro_name or config_path or str(build_file_path), - run_config=run_config_file.as_posix() if run_config_file else None, - ) - if return_code != 0: - raise RuntimeError(f"Failed to build image {image_name}") - - if distro_name: - # copy run.yaml from distribution to build_dir instead of generating it again - distro_path = importlib.resources.files("llama_stack") / f"distributions/{distro_name}/run.yaml" - run_config_file = build_dir / f"{distro_name}-run.yaml" - - with importlib.resources.as_file(distro_path) as path: - shutil.copy(path, run_config_file) - - cprint("Build Successful!", color="green", file=sys.stderr) - cprint(f"You can find the newly-built distribution here: {run_config_file}", color="blue", file=sys.stderr) - if build_config.image_type == LlamaStackImageType.VENV: - cprint( - "You can run the new Llama Stack distro (after activating " - + colored(image_name, "cyan") - + ") via: " - + colored(f"llama stack run {run_config_file}", "blue"), - color="green", - file=sys.stderr, - ) - elif build_config.image_type == LlamaStackImageType.CONTAINER: - cprint( - "You can run the container with: " - + colored( - f"docker run -p 8321:8321 -v ~/.llama:/root/.llama localhost/{image_name} --port 8321", "blue" - ), - color="green", - file=sys.stderr, - ) - return distro_path - else: - return _generate_run_config(build_config, build_dir, image_name) - - -def _run_distro_list_cmd() -> None: - headers = [ - "Distribution Name", - # "Providers", - "Description", - ] - - rows = [] - for distro_name, spec in available_distros_specs().items(): - rows.append( - [ - distro_name, - # json.dumps(spec.distribution_spec.providers, indent=2), - spec.distribution_spec.description, - ] - ) - print_table( - rows, - headers, - separate_rows=True, - ) diff --git a/llama_stack/cli/stack/build.py b/llama_stack/cli/stack/build.py deleted file mode 100644 index cbe8ed881..000000000 --- a/llama_stack/cli/stack/build.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under the terms described in the LICENSE file in -# the root directory of this source tree. -import argparse -import textwrap - -from llama_stack.cli.stack.utils import ImageType -from llama_stack.cli.subcommand import Subcommand -from llama_stack.log import get_logger - -logger = get_logger(__name__, category="cli") - - -class StackBuild(Subcommand): - def __init__(self, subparsers: argparse._SubParsersAction): - super().__init__() - self.parser = subparsers.add_parser( - "build", - prog="llama stack build", - description="[DEPRECATED] Build a Llama stack container. This command is deprecated and will be removed in a future release. Use `llama stack list-deps ' instead.", - formatter_class=argparse.ArgumentDefaultsHelpFormatter, - ) - self._add_arguments() - self.parser.set_defaults(func=self._run_stack_build_command) - - def _add_arguments(self): - self.parser.add_argument( - "--config", - type=str, - default=None, - help="Path to a config file to use for the build. You can find example configs in llama_stack.cores/**/build.yaml. If this argument is not provided, you will be prompted to enter information interactively", - ) - - self.parser.add_argument( - "--template", - type=str, - default=None, - help="""(deprecated) Name of the example template config to use for build. You may use `llama stack build --list-distros` to check out the available distributions""", - ) - self.parser.add_argument( - "--distro", - "--distribution", - dest="distribution", - type=str, - default=None, - help="""Name of the distribution to use for build. You may use `llama stack build --list-distros` to check out the available distributions""", - ) - - self.parser.add_argument( - "--list-distros", - "--list-distributions", - action="store_true", - dest="list_distros", - default=False, - help="Show the available distributions for building a Llama Stack distribution", - ) - - self.parser.add_argument( - "--image-type", - type=str, - help="Image Type to use for the build. If not specified, will use the image type from the template config.", - choices=[e.value for e in ImageType], - default=None, # no default so we can detect if a user specified --image-type and override image_type in the config - ) - - self.parser.add_argument( - "--image-name", - type=str, - help=textwrap.dedent( - f"""[for image-type={"|".join(e.value for e in ImageType)}] Name of the virtual environment to use for -the build. If not specified, currently active environment will be used if found. - """ - ), - default=None, - ) - self.parser.add_argument( - "--print-deps-only", - default=False, - action="store_true", - help="Print the dependencies for the stack only, without building the stack", - ) - - self.parser.add_argument( - "--run", - action="store_true", - default=False, - help="Run the stack after building using the same image type, name, and other applicable arguments", - ) - self.parser.add_argument( - "--providers", - type=str, - default=None, - help="Build a config for a list of providers and only those providers. This list is formatted like: api1=provider1,api2=provider2. Where there can be multiple providers per API.", - ) - - def _run_stack_build_command(self, args: argparse.Namespace) -> None: - logger.warning( - "The 'llama stack build' command is deprecated and will be removed in a future release. Please use 'llama stack list-deps'" - ) - # always keep implementation completely silo-ed away from CLI so CLI - # can be fast to load and reduces dependencies - from ._build import run_stack_build_command - - return run_stack_build_command(args) diff --git a/llama_stack/cli/stack/stack.py b/llama_stack/cli/stack/stack.py index fd0a4edf5..351da972f 100644 --- a/llama_stack/cli/stack/stack.py +++ b/llama_stack/cli/stack/stack.py @@ -11,7 +11,6 @@ from llama_stack.cli.stack.list_stacks import StackListBuilds from llama_stack.cli.stack.utils import print_subcommand_description from llama_stack.cli.subcommand import Subcommand -from .build import StackBuild from .list_apis import StackListApis from .list_deps import StackListDeps from .list_providers import StackListProviders @@ -41,7 +40,6 @@ class StackParser(Subcommand): # Add sub-commands StackListDeps.create(subparsers) - StackBuild.create(subparsers) StackListApis.create(subparsers) StackListProviders.create(subparsers) StackRun.create(subparsers) diff --git a/llama_stack/cli/stack/utils.py b/llama_stack/cli/stack/utils.py index 4d4c1b538..cc1ca051b 100644 --- a/llama_stack/cli/stack/utils.py +++ b/llama_stack/cli/stack/utils.py @@ -17,10 +17,19 @@ from llama_stack.core.datatypes import ( BuildConfig, Provider, StackRunConfig, + StorageConfig, ) from llama_stack.core.distribution import get_provider_registry from llama_stack.core.resolver import InvalidProviderError -from llama_stack.core.utils.config_dirs import EXTERNAL_PROVIDERS_DIR +from llama_stack.core.storage.datatypes import ( + InferenceStoreReference, + KVStoreReference, + ServerStoresConfig, + SqliteKVStoreConfig, + SqliteSqlStoreConfig, + SqlStoreReference, +) +from llama_stack.core.utils.config_dirs import DISTRIBS_BASE_DIR, EXTERNAL_PROVIDERS_DIR from llama_stack.core.utils.dynamic import instantiate_class_type from llama_stack.core.utils.image_types import LlamaStackImageType from llama_stack.providers.datatypes import Api @@ -51,11 +60,23 @@ def generate_run_config( Generate a run.yaml template file for user to edit from a build.yaml file """ apis = list(build_config.distribution_spec.providers.keys()) + distro_dir = DISTRIBS_BASE_DIR / image_name run_config = StackRunConfig( container_image=(image_name if build_config.image_type == LlamaStackImageType.CONTAINER.value else None), image_name=image_name, apis=apis, providers={}, + storage=StorageConfig( + backends={ + "kv_default": SqliteKVStoreConfig(db_path=str(distro_dir / "kvstore.db")), + "sql_default": SqliteSqlStoreConfig(db_path=str(distro_dir / "sql_store.db")), + }, + stores=ServerStoresConfig( + metadata=KVStoreReference(backend="kv_default", namespace="registry"), + inference=InferenceStoreReference(backend="sql_default", table_name="inference_store"), + conversations=SqlStoreReference(backend="sql_default", table_name="openai_conversations"), + ), + ), external_providers_dir=build_config.external_providers_dir if build_config.external_providers_dir else EXTERNAL_PROVIDERS_DIR, diff --git a/llama_stack/core/access_control/datatypes.py b/llama_stack/core/access_control/datatypes.py index c833ed51b..84beb8e15 100644 --- a/llama_stack/core/access_control/datatypes.py +++ b/llama_stack/core/access_control/datatypes.py @@ -41,7 +41,7 @@ class AccessRule(BaseModel): A rule defines a list of action either to permit or to forbid. It may specify a principal or a resource that must match for the rule to take effect. The resource to match should be specified in the form of a type qualified identifier, e.g. - model::my-model or vector_db::some-db, or a wildcard for all resources of a type, + model::my-model or vector_store::some-db, or a wildcard for all resources of a type, e.g. model::*. If the principal or resource are not specified, they will match all requests. @@ -79,9 +79,9 @@ class AccessRule(BaseModel): description: any user has read access to any resource created by a member of their team - forbid: actions: [create, read, delete] - resource: vector_db::* + resource: vector_store::* unless: user with admin in roles - description: only user with admin role can use vector_db resources + description: only user with admin role can use vector_store resources """ diff --git a/llama_stack/core/build_container.sh b/llama_stack/core/build_container.sh deleted file mode 100755 index 03ed846d9..000000000 --- a/llama_stack/core/build_container.sh +++ /dev/null @@ -1,410 +0,0 @@ -#!/usr/bin/env bash - -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under the terms described in the LICENSE file in -# the root directory of this source tree. - -LLAMA_STACK_DIR=${LLAMA_STACK_DIR:-} -LLAMA_STACK_CLIENT_DIR=${LLAMA_STACK_CLIENT_DIR:-} - -TEST_PYPI_VERSION=${TEST_PYPI_VERSION:-} -PYPI_VERSION=${PYPI_VERSION:-} -BUILD_PLATFORM=${BUILD_PLATFORM:-} -# This timeout (in seconds) is necessary when installing PyTorch via uv since it's likely to time out -# Reference: https://github.com/astral-sh/uv/pull/1694 -UV_HTTP_TIMEOUT=${UV_HTTP_TIMEOUT:-500} - -# mounting is not supported by docker buildx, so we use COPY instead -USE_COPY_NOT_MOUNT=${USE_COPY_NOT_MOUNT:-} -# Path to the run.yaml file in the container -RUN_CONFIG_PATH=/app/run.yaml - -BUILD_CONTEXT_DIR=$(pwd) - -set -euo pipefail - -# Define color codes -RED='\033[0;31m' -NC='\033[0m' # No Color - -# Usage function -usage() { - echo "Usage: $0 --image-name --container-base --normal-deps [--run-config ] [--external-provider-deps ] [--optional-deps ]" - echo "Example: $0 --image-name llama-stack-img --container-base python:3.12-slim --normal-deps 'numpy pandas' --run-config ./run.yaml --external-provider-deps 'foo' --optional-deps 'bar'" - exit 1 -} - -# Parse arguments -image_name="" -container_base="" -normal_deps="" -external_provider_deps="" -optional_deps="" -run_config="" -distro_or_config="" - -while [[ $# -gt 0 ]]; do - key="$1" - case "$key" in - --image-name) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --image-name requires a string value" >&2 - usage - fi - image_name="$2" - shift 2 - ;; - --container-base) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --container-base requires a string value" >&2 - usage - fi - container_base="$2" - shift 2 - ;; - --normal-deps) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --normal-deps requires a string value" >&2 - usage - fi - normal_deps="$2" - shift 2 - ;; - --external-provider-deps) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --external-provider-deps requires a string value" >&2 - usage - fi - external_provider_deps="$2" - shift 2 - ;; - --optional-deps) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --optional-deps requires a string value" >&2 - usage - fi - optional_deps="$2" - shift 2 - ;; - --run-config) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --run-config requires a string value" >&2 - usage - fi - run_config="$2" - shift 2 - ;; - --distro-or-config) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --distro-or-config requires a string value" >&2 - usage - fi - distro_or_config="$2" - shift 2 - ;; - *) - echo "Unknown option: $1" >&2 - usage - ;; - esac -done - -# Check required arguments -if [[ -z "$image_name" || -z "$container_base" || -z "$normal_deps" ]]; then - echo "Error: --image-name, --container-base, and --normal-deps are required." >&2 - usage -fi - -CONTAINER_BINARY=${CONTAINER_BINARY:-docker} -CONTAINER_OPTS=${CONTAINER_OPTS:---progress=plain} -TEMP_DIR=$(mktemp -d) -SCRIPT_DIR=$(dirname "$(readlink -f "$0")") -source "$SCRIPT_DIR/common.sh" - -add_to_container() { - output_file="$TEMP_DIR/Containerfile" - if [ -t 0 ]; then - printf '%s\n' "$1" >>"$output_file" - else - cat >>"$output_file" - fi -} - -if ! is_command_available "$CONTAINER_BINARY"; then - printf "${RED}Error: ${CONTAINER_BINARY} command not found. Is ${CONTAINER_BINARY} installed and in your PATH?${NC}" >&2 - exit 1 -fi - -if [[ $container_base == *"registry.access.redhat.com/ubi9"* ]]; then - add_to_container << EOF -FROM $container_base -WORKDIR /app - -# We install the Python 3.12 dev headers and build tools so that any -# C-extension wheels (e.g. polyleven, faiss-cpu) can compile successfully. - -RUN dnf -y update && dnf install -y iputils git net-tools wget \ - vim-minimal python3.12 python3.12-pip python3.12-wheel \ - python3.12-setuptools python3.12-devel gcc gcc-c++ make && \ - ln -s /bin/pip3.12 /bin/pip && ln -s /bin/python3.12 /bin/python && dnf clean all - -ENV UV_SYSTEM_PYTHON=1 -RUN pip install uv -EOF -else - add_to_container << EOF -FROM $container_base -WORKDIR /app - -RUN apt-get update && apt-get install -y \ - iputils-ping net-tools iproute2 dnsutils telnet \ - curl wget telnet git\ - procps psmisc lsof \ - traceroute \ - bubblewrap \ - gcc g++ \ - && rm -rf /var/lib/apt/lists/* - -ENV UV_SYSTEM_PYTHON=1 -RUN pip install uv -EOF -fi - -# Add pip dependencies first since llama-stack is what will change most often -# so we can reuse layers. -if [ -n "$normal_deps" ]; then - read -ra pip_args <<< "$normal_deps" - quoted_deps=$(printf " %q" "${pip_args[@]}") - add_to_container << EOF -RUN uv pip install --no-cache $quoted_deps -EOF -fi - -if [ -n "$optional_deps" ]; then - IFS='#' read -ra parts <<<"$optional_deps" - for part in "${parts[@]}"; do - read -ra pip_args <<< "$part" - quoted_deps=$(printf " %q" "${pip_args[@]}") - add_to_container <=')[0].split('<=')[0].split('!=')[0].split('<')[0].split('>')[0] - module = importlib.import_module(f'{package_name}.provider') - spec = module.get_provider_spec() - if hasattr(spec, 'pip_packages') and spec.pip_packages: - if isinstance(spec.pip_packages, (list, tuple)): - print('\n'.join(spec.pip_packages)) -except Exception as e: - print(f'Error getting provider spec for {package_name}: {e}', file=sys.stderr) -PYTHON -EOF - done -fi - -get_python_cmd() { - if is_command_available python; then - echo "python" - elif is_command_available python3; then - echo "python3" - else - echo "Error: Neither python nor python3 is installed. Please install Python to continue." >&2 - exit 1 - fi -} - -if [ -n "$run_config" ]; then - # Copy the run config to the build context since it's an absolute path - cp "$run_config" "$BUILD_CONTEXT_DIR/run.yaml" - - # Parse the run.yaml configuration to identify external provider directories - # If external providers are specified, copy their directory to the container - # and update the configuration to reference the new container path - python_cmd=$(get_python_cmd) - external_providers_dir=$($python_cmd -c "import yaml; config = yaml.safe_load(open('$run_config')); print(config.get('external_providers_dir') or '')") - external_providers_dir=$(eval echo "$external_providers_dir") - if [ -n "$external_providers_dir" ]; then - if [ -d "$external_providers_dir" ]; then - echo "Copying external providers directory: $external_providers_dir" - cp -r "$external_providers_dir" "$BUILD_CONTEXT_DIR/providers.d" - add_to_container << EOF -COPY providers.d /.llama/providers.d -EOF - fi - - # Edit the run.yaml file to change the external_providers_dir to /.llama/providers.d - if [ "$(uname)" = "Darwin" ]; then - sed -i.bak -e 's|external_providers_dir:.*|external_providers_dir: /.llama/providers.d|' "$BUILD_CONTEXT_DIR/run.yaml" - rm -f "$BUILD_CONTEXT_DIR/run.yaml.bak" - else - sed -i 's|external_providers_dir:.*|external_providers_dir: /.llama/providers.d|' "$BUILD_CONTEXT_DIR/run.yaml" - fi - fi - - # Copy run config into docker image - add_to_container << EOF -COPY run.yaml $RUN_CONFIG_PATH -EOF -fi - -stack_mount="/app/llama-stack-source" -client_mount="/app/llama-stack-client-source" - -install_local_package() { - local dir="$1" - local mount_point="$2" - local name="$3" - - if [ ! -d "$dir" ]; then - echo "${RED}Warning: $name is set but directory does not exist: $dir${NC}" >&2 - exit 1 - fi - - if [ "$USE_COPY_NOT_MOUNT" = "true" ]; then - add_to_container << EOF -COPY $dir $mount_point -EOF - fi - add_to_container << EOF -RUN uv pip install --no-cache -e $mount_point -EOF -} - - -if [ -n "$LLAMA_STACK_CLIENT_DIR" ]; then - install_local_package "$LLAMA_STACK_CLIENT_DIR" "$client_mount" "LLAMA_STACK_CLIENT_DIR" -fi - -if [ -n "$LLAMA_STACK_DIR" ]; then - install_local_package "$LLAMA_STACK_DIR" "$stack_mount" "LLAMA_STACK_DIR" -else - if [ -n "$TEST_PYPI_VERSION" ]; then - # these packages are damaged in test-pypi, so install them first - add_to_container << EOF -RUN uv pip install --no-cache fastapi libcst -EOF - add_to_container << EOF -RUN uv pip install --no-cache --extra-index-url https://test.pypi.org/simple/ \ - --index-strategy unsafe-best-match \ - llama-stack==$TEST_PYPI_VERSION - -EOF - else - if [ -n "$PYPI_VERSION" ]; then - SPEC_VERSION="llama-stack==${PYPI_VERSION}" - else - SPEC_VERSION="llama-stack" - fi - add_to_container << EOF -RUN uv pip install --no-cache $SPEC_VERSION -EOF - fi -fi - -# remove uv after installation - add_to_container << EOF -RUN pip uninstall -y uv -EOF - -# If a run config is provided, we use the llama stack CLI -if [[ -n "$run_config" ]]; then - add_to_container << EOF -ENTRYPOINT ["llama", "stack", "run", "$RUN_CONFIG_PATH"] -EOF -elif [[ "$distro_or_config" != *.yaml ]]; then - add_to_container << EOF -ENTRYPOINT ["llama", "stack", "run", "$distro_or_config"] -EOF -fi - -# Add other require item commands genearic to all containers -add_to_container << EOF - -RUN mkdir -p /.llama /.cache && chmod -R g+rw /.llama /.cache && (chmod -R g+rw /app 2>/dev/null || true) -EOF - -printf "Containerfile created successfully in %s/Containerfile\n\n" "$TEMP_DIR" -cat "$TEMP_DIR"/Containerfile -printf "\n" - -# Start building the CLI arguments -CLI_ARGS=() - -# Read CONTAINER_OPTS and put it in an array -read -ra CLI_ARGS <<< "$CONTAINER_OPTS" - -if [ "$USE_COPY_NOT_MOUNT" != "true" ]; then - if [ -n "$LLAMA_STACK_DIR" ]; then - CLI_ARGS+=("-v" "$(readlink -f "$LLAMA_STACK_DIR"):$stack_mount") - fi - if [ -n "$LLAMA_STACK_CLIENT_DIR" ]; then - CLI_ARGS+=("-v" "$(readlink -f "$LLAMA_STACK_CLIENT_DIR"):$client_mount") - fi -fi - -if is_command_available selinuxenabled && selinuxenabled; then - # Disable SELinux labels -- we don't want to relabel the llama-stack source dir - CLI_ARGS+=("--security-opt" "label=disable") -fi - -# Set version tag based on PyPI version -if [ -n "$PYPI_VERSION" ]; then - version_tag="$PYPI_VERSION" -elif [ -n "$TEST_PYPI_VERSION" ]; then - version_tag="test-$TEST_PYPI_VERSION" -elif [[ -n "$LLAMA_STACK_DIR" || -n "$LLAMA_STACK_CLIENT_DIR" ]]; then - version_tag="dev" -else - URL="https://pypi.org/pypi/llama-stack/json" - version_tag=$(curl -s $URL | jq -r '.info.version') -fi - -# Add version tag to image name -image_tag="$image_name:$version_tag" - -# Detect platform architecture -ARCH=$(uname -m) -if [ -n "$BUILD_PLATFORM" ]; then - CLI_ARGS+=("--platform" "$BUILD_PLATFORM") -elif [ "$ARCH" = "arm64" ] || [ "$ARCH" = "aarch64" ]; then - CLI_ARGS+=("--platform" "linux/arm64") -elif [ "$ARCH" = "x86_64" ]; then - CLI_ARGS+=("--platform" "linux/amd64") -else - echo "Unsupported architecture: $ARCH" - exit 1 -fi - -echo "PWD: $(pwd)" -echo "Containerfile: $TEMP_DIR/Containerfile" -set -x - -$CONTAINER_BINARY build \ - "${CLI_ARGS[@]}" \ - -t "$image_tag" \ - -f "$TEMP_DIR/Containerfile" \ - "$BUILD_CONTEXT_DIR" - -# clean up tmp/configs -rm -rf "$BUILD_CONTEXT_DIR/run.yaml" "$TEMP_DIR" -set +x - -echo "Success!" diff --git a/llama_stack/core/build_venv.sh b/llama_stack/core/build_venv.sh deleted file mode 100755 index 04927d71e..000000000 --- a/llama_stack/core/build_venv.sh +++ /dev/null @@ -1,220 +0,0 @@ -#!/bin/bash - -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under the terms described in the LICENSE file in -# the root directory of this source tree. - -LLAMA_STACK_DIR=${LLAMA_STACK_DIR:-} -LLAMA_STACK_CLIENT_DIR=${LLAMA_STACK_CLIENT_DIR:-} -TEST_PYPI_VERSION=${TEST_PYPI_VERSION:-} -# This timeout (in seconds) is necessary when installing PyTorch via uv since it's likely to time out -# Reference: https://github.com/astral-sh/uv/pull/1694 -UV_HTTP_TIMEOUT=${UV_HTTP_TIMEOUT:-500} -UV_SYSTEM_PYTHON=${UV_SYSTEM_PYTHON:-} -VIRTUAL_ENV=${VIRTUAL_ENV:-} - -set -euo pipefail - -# Define color codes -RED='\033[0;31m' -NC='\033[0m' # No Color - -SCRIPT_DIR=$(dirname "$(readlink -f "$0")") -source "$SCRIPT_DIR/common.sh" - -# Usage function -usage() { - echo "Usage: $0 --env-name --normal-deps [--external-provider-deps ] [--optional-deps ]" - echo "Example: $0 --env-name mybuild --normal-deps 'numpy pandas scipy' --external-provider-deps 'foo' --optional-deps 'bar'" - exit 1 -} - -# Parse arguments -env_name="" -normal_deps="" -external_provider_deps="" -optional_deps="" - -while [[ $# -gt 0 ]]; do - key="$1" - case "$key" in - --env-name) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --env-name requires a string value" >&2 - usage - fi - env_name="$2" - shift 2 - ;; - --normal-deps) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --normal-deps requires a string value" >&2 - usage - fi - normal_deps="$2" - shift 2 - ;; - --external-provider-deps) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --external-provider-deps requires a string value" >&2 - usage - fi - external_provider_deps="$2" - shift 2 - ;; - --optional-deps) - if [[ -z "$2" || "$2" == --* ]]; then - echo "Error: --optional-deps requires a string value" >&2 - usage - fi - optional_deps="$2" - shift 2 - ;; - *) - echo "Unknown option: $1" >&2 - usage - ;; - esac -done - -# Check required arguments -if [[ -z "$env_name" || -z "$normal_deps" ]]; then - echo "Error: --env-name and --normal-deps are required." >&2 - usage -fi - -if [ -n "$LLAMA_STACK_DIR" ]; then - echo "Using llama-stack-dir=$LLAMA_STACK_DIR" -fi -if [ -n "$LLAMA_STACK_CLIENT_DIR" ]; then - echo "Using llama-stack-client-dir=$LLAMA_STACK_CLIENT_DIR" -fi - -ENVNAME="" - -# pre-run checks to make sure we can proceed with the installation -pre_run_checks() { - local env_name="$1" - - if ! is_command_available uv; then - echo "uv is not installed, trying to install it." - if ! is_command_available pip; then - echo "pip is not installed, cannot automatically install 'uv'." - echo "Follow this link to install it:" - echo "https://docs.astral.sh/uv/getting-started/installation/" - exit 1 - else - pip install uv - fi - fi - - # checking if an environment with the same name already exists - if [ -d "$env_name" ]; then - echo "Environment '$env_name' already exists, re-using it." - fi -} - -run() { - # Use only global variables set by flag parser - if [ -n "$UV_SYSTEM_PYTHON" ] || [ "$env_name" == "__system__" ]; then - echo "Installing dependencies in system Python environment" - export UV_SYSTEM_PYTHON=1 - elif [ "$VIRTUAL_ENV" == "$env_name" ]; then - echo "Virtual environment $env_name is already active" - else - echo "Using virtual environment $env_name" - uv venv "$env_name" - source "$env_name/bin/activate" - fi - - if [ -n "$TEST_PYPI_VERSION" ]; then - uv pip install fastapi libcst - uv pip install --extra-index-url https://test.pypi.org/simple/ \ - --index-strategy unsafe-best-match \ - llama-stack=="$TEST_PYPI_VERSION" \ - $normal_deps - if [ -n "$optional_deps" ]; then - IFS='#' read -ra parts <<<"$optional_deps" - for part in "${parts[@]}"; do - echo "$part" - uv pip install $part - done - fi - if [ -n "$external_provider_deps" ]; then - IFS='#' read -ra parts <<<"$external_provider_deps" - for part in "${parts[@]}"; do - echo "$part" - uv pip install "$part" - done - fi - else - if [ -n "$LLAMA_STACK_DIR" ]; then - # only warn if DIR does not start with "git+" - if [ ! -d "$LLAMA_STACK_DIR" ] && [[ "$LLAMA_STACK_DIR" != git+* ]]; then - printf "${RED}Warning: LLAMA_STACK_DIR is set but directory does not exist: %s${NC}\n" "$LLAMA_STACK_DIR" >&2 - exit 1 - fi - printf "Installing from LLAMA_STACK_DIR: %s\n" "$LLAMA_STACK_DIR" - # editable only if LLAMA_STACK_DIR does not start with "git+" - if [[ "$LLAMA_STACK_DIR" != git+* ]]; then - EDITABLE="-e" - else - EDITABLE="" - fi - uv pip install --no-cache-dir $EDITABLE "$LLAMA_STACK_DIR" - else - uv pip install --no-cache-dir llama-stack - fi - - if [ -n "$LLAMA_STACK_CLIENT_DIR" ]; then - # only warn if DIR does not start with "git+" - if [ ! -d "$LLAMA_STACK_CLIENT_DIR" ] && [[ "$LLAMA_STACK_CLIENT_DIR" != git+* ]]; then - printf "${RED}Warning: LLAMA_STACK_CLIENT_DIR is set but directory does not exist: %s${NC}\n" "$LLAMA_STACK_CLIENT_DIR" >&2 - exit 1 - fi - printf "Installing from LLAMA_STACK_CLIENT_DIR: %s\n" "$LLAMA_STACK_CLIENT_DIR" - # editable only if LLAMA_STACK_CLIENT_DIR does not start with "git+" - if [[ "$LLAMA_STACK_CLIENT_DIR" != git+* ]]; then - EDITABLE="-e" - else - EDITABLE="" - fi - uv pip install --no-cache-dir $EDITABLE "$LLAMA_STACK_CLIENT_DIR" - fi - - printf "Installing pip dependencies\n" - uv pip install $normal_deps - if [ -n "$optional_deps" ]; then - IFS='#' read -ra parts <<<"$optional_deps" - for part in "${parts[@]}"; do - echo "Installing special provider module: $part" - uv pip install $part - done - fi - if [ -n "$external_provider_deps" ]; then - IFS='#' read -ra parts <<<"$external_provider_deps" - for part in "${parts[@]}"; do - echo "Installing external provider module: $part" - uv pip install "$part" - echo "Getting provider spec for module: $part and installing dependencies" - package_name=$(echo "$part" | sed 's/[<>=!].*//') - python3 -c " -import importlib -import sys -try: - module = importlib.import_module(f'$package_name.provider') - spec = module.get_provider_spec() - if hasattr(spec, 'pip_packages') and spec.pip_packages: - print('\\n'.join(spec.pip_packages)) -except Exception as e: - print(f'Error getting provider spec for $package_name: {e}', file=sys.stderr) -" | uv pip install -r - - done - fi - fi -} - -pre_run_checks "$env_name" -run diff --git a/llama_stack/core/configure.py b/llama_stack/core/configure.py index bfa2c6d71..734839ea9 100644 --- a/llama_stack/core/configure.py +++ b/llama_stack/core/configure.py @@ -159,6 +159,37 @@ def upgrade_from_routing_table( config_dict["apis"] = config_dict["apis_to_serve"] config_dict.pop("apis_to_serve", None) + # Add default storage config if not present + if "storage" not in config_dict: + config_dict["storage"] = { + "backends": { + "kv_default": { + "type": "kv_sqlite", + "db_path": "~/.llama/kvstore.db", + }, + "sql_default": { + "type": "sql_sqlite", + "db_path": "~/.llama/sql_store.db", + }, + }, + "stores": { + "metadata": { + "namespace": "registry", + "backend": "kv_default", + }, + "inference": { + "table_name": "inference_store", + "backend": "sql_default", + "max_write_queue_size": 10000, + "num_writers": 4, + }, + "conversations": { + "table_name": "openai_conversations", + "backend": "sql_default", + }, + }, + } + return config_dict diff --git a/llama_stack/core/conversations/conversations.py b/llama_stack/core/conversations/conversations.py index d2537c7ee..66880ca36 100644 --- a/llama_stack/core/conversations/conversations.py +++ b/llama_stack/core/conversations/conversations.py @@ -4,7 +4,6 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -import os import secrets import time from typing import Any @@ -21,16 +20,11 @@ from llama_stack.apis.conversations.conversations import ( Conversations, Metadata, ) -from llama_stack.core.datatypes import AccessRule -from llama_stack.core.utils.config_dirs import DISTRIBS_BASE_DIR +from llama_stack.core.datatypes import AccessRule, StackRunConfig from llama_stack.log import get_logger from llama_stack.providers.utils.sqlstore.api import ColumnDefinition, ColumnType from llama_stack.providers.utils.sqlstore.authorized_sqlstore import AuthorizedSqlStore -from llama_stack.providers.utils.sqlstore.sqlstore import ( - SqliteSqlStoreConfig, - SqlStoreConfig, - sqlstore_impl, -) +from llama_stack.providers.utils.sqlstore.sqlstore import sqlstore_impl logger = get_logger(name=__name__, category="openai_conversations") @@ -38,13 +32,11 @@ logger = get_logger(name=__name__, category="openai_conversations") class ConversationServiceConfig(BaseModel): """Configuration for the built-in conversation service. - :param conversations_store: SQL store configuration for conversations (defaults to SQLite) + :param run_config: Stack run configuration for resolving persistence :param policy: Access control rules """ - conversations_store: SqlStoreConfig = SqliteSqlStoreConfig( - db_path=(DISTRIBS_BASE_DIR / "conversations.db").as_posix() - ) + run_config: StackRunConfig policy: list[AccessRule] = [] @@ -63,14 +55,16 @@ class ConversationServiceImpl(Conversations): self.deps = deps self.policy = config.policy - base_sql_store = sqlstore_impl(config.conversations_store) + # Use conversations store reference from run config + conversations_ref = config.run_config.storage.stores.conversations + if not conversations_ref: + raise ValueError("storage.stores.conversations must be configured in run config") + + base_sql_store = sqlstore_impl(conversations_ref) self.sql_store = AuthorizedSqlStore(base_sql_store, self.policy) async def initialize(self) -> None: """Initialize the store and create tables.""" - if isinstance(self.config.conversations_store, SqliteSqlStoreConfig): - os.makedirs(os.path.dirname(self.config.conversations_store.db_path), exist_ok=True) - await self.sql_store.create_table( "openai_conversations", { diff --git a/llama_stack/core/datatypes.py b/llama_stack/core/datatypes.py index 94222d49e..5f4775d87 100644 --- a/llama_stack/core/datatypes.py +++ b/llama_stack/core/datatypes.py @@ -23,12 +23,15 @@ from llama_stack.apis.scoring import Scoring from llama_stack.apis.scoring_functions import ScoringFn, ScoringFnInput from llama_stack.apis.shields import Shield, ShieldInput from llama_stack.apis.tools import ToolGroup, ToolGroupInput, ToolRuntime -from llama_stack.apis.vector_dbs import VectorDB, VectorDBInput from llama_stack.apis.vector_io import VectorIO +from llama_stack.apis.vector_stores import VectorStore, VectorStoreInput from llama_stack.core.access_control.datatypes import AccessRule +from llama_stack.core.storage.datatypes import ( + KVStoreReference, + StorageBackendType, + StorageConfig, +) from llama_stack.providers.datatypes import Api, ProviderSpec -from llama_stack.providers.utils.kvstore.config import KVStoreConfig, SqliteKVStoreConfig -from llama_stack.providers.utils.sqlstore.sqlstore import SqlStoreConfig LLAMA_STACK_BUILD_CONFIG_VERSION = 2 LLAMA_STACK_RUN_CONFIG_VERSION = 2 @@ -68,7 +71,7 @@ class ShieldWithOwner(Shield, ResourceWithOwner): pass -class VectorDBWithOwner(VectorDB, ResourceWithOwner): +class VectorStoreWithOwner(VectorStore, ResourceWithOwner): pass @@ -88,12 +91,12 @@ class ToolGroupWithOwner(ToolGroup, ResourceWithOwner): pass -RoutableObject = Model | Shield | VectorDB | Dataset | ScoringFn | Benchmark | ToolGroup +RoutableObject = Model | Shield | VectorStore | Dataset | ScoringFn | Benchmark | ToolGroup RoutableObjectWithProvider = Annotated[ ModelWithOwner | ShieldWithOwner - | VectorDBWithOwner + | VectorStoreWithOwner | DatasetWithOwner | ScoringFnWithOwner | BenchmarkWithOwner @@ -351,12 +354,32 @@ class AuthenticationRequiredError(Exception): pass +class QualifiedModel(BaseModel): + """A qualified model identifier, consisting of a provider ID and a model ID.""" + + provider_id: str + model_id: str + + +class VectorStoresConfig(BaseModel): + """Configuration for vector stores in the stack.""" + + default_provider_id: str | None = Field( + default=None, + description="ID of the vector_io provider to use as default when multiple providers are available and none is specified.", + ) + default_embedding_model: QualifiedModel | None = Field( + default=None, + description="Default embedding model configuration for vector stores.", + ) + + class QuotaPeriod(StrEnum): DAY = "day" class QuotaConfig(BaseModel): - kvstore: SqliteKVStoreConfig = Field(description="Config for KV store backend (SQLite only for now)") + kvstore: KVStoreReference = Field(description="Config for KV store backend (SQLite only for now)") anonymous_max_requests: int = Field(default=100, description="Max requests for unauthenticated clients per period") authenticated_max_requests: int = Field( default=1000, description="Max requests for authenticated clients per period" @@ -399,6 +422,18 @@ def process_cors_config(cors_config: bool | CORSConfig | None) -> CORSConfig | N raise ValueError(f"Expected bool or CORSConfig, got {type(cors_config).__name__}") +class RegisteredResources(BaseModel): + """Registry of resources available in the distribution.""" + + models: list[ModelInput] = Field(default_factory=list) + shields: list[ShieldInput] = Field(default_factory=list) + vector_stores: list[VectorStoreInput] = Field(default_factory=list) + datasets: list[DatasetInput] = Field(default_factory=list) + scoring_fns: list[ScoringFnInput] = Field(default_factory=list) + benchmarks: list[BenchmarkInput] = Field(default_factory=list) + tool_groups: list[ToolGroupInput] = Field(default_factory=list) + + class ServerConfig(BaseModel): port: int = Field( default=8321, @@ -438,18 +473,6 @@ class ServerConfig(BaseModel): ) -class InferenceStoreConfig(BaseModel): - sql_store_config: SqlStoreConfig - max_write_queue_size: int = Field(default=10000, description="Max queued writes for inference store") - num_writers: int = Field(default=4, description="Number of concurrent background writers") - - -class ResponsesStoreConfig(BaseModel): - sql_store_config: SqlStoreConfig - max_write_queue_size: int = Field(default=10000, description="Max queued writes for responses store") - num_writers: int = Field(default=4, description="Number of concurrent background writers") - - class StackRunConfig(BaseModel): version: int = LLAMA_STACK_RUN_CONFIG_VERSION @@ -476,37 +499,15 @@ One or more providers to use for each API. The same provider_type (e.g., meta-re can be instantiated multiple times (with different configs) if necessary. """, ) - metadata_store: KVStoreConfig | None = Field( - default=None, - description=""" -Configuration for the persistence store used by the distribution registry. If not specified, -a default SQLite store will be used.""", + storage: StorageConfig = Field( + description="Catalog of named storage backends and references available to the stack", ) - inference_store: InferenceStoreConfig | SqlStoreConfig | None = Field( - default=None, - description=""" -Configuration for the persistence store used by the inference API. Can be either a -InferenceStoreConfig (with queue tuning parameters) or a SqlStoreConfig (deprecated). -If not specified, a default SQLite store will be used.""", + registered_resources: RegisteredResources = Field( + default_factory=RegisteredResources, + description="Registry of resources available in the distribution", ) - conversations_store: SqlStoreConfig | None = Field( - default=None, - description=""" -Configuration for the persistence store used by the conversations API. -If not specified, a default SQLite store will be used.""", - ) - - # registry of "resources" in the distribution - models: list[ModelInput] = Field(default_factory=list) - shields: list[ShieldInput] = Field(default_factory=list) - vector_dbs: list[VectorDBInput] = Field(default_factory=list) - datasets: list[DatasetInput] = Field(default_factory=list) - scoring_fns: list[ScoringFnInput] = Field(default_factory=list) - benchmarks: list[BenchmarkInput] = Field(default_factory=list) - tool_groups: list[ToolGroupInput] = Field(default_factory=list) - logging: LoggingConfig | None = Field(default=None, description="Configuration for Llama Stack Logging") telemetry: TelemetryConfig = Field(default_factory=TelemetryConfig, description="Configuration for telemetry") @@ -526,6 +527,11 @@ If not specified, a default SQLite store will be used.""", description="Path to directory containing external API implementations. The APIs code and dependencies must be installed on the system.", ) + vector_stores: VectorStoresConfig | None = Field( + default=None, + description="Configuration for vector stores, including default embedding model", + ) + @field_validator("external_providers_dir") @classmethod def validate_external_providers_dir(cls, v): @@ -535,6 +541,49 @@ If not specified, a default SQLite store will be used.""", return Path(v) return v + @model_validator(mode="after") + def validate_server_stores(self) -> "StackRunConfig": + backend_map = self.storage.backends + stores = self.storage.stores + kv_backends = { + name + for name, cfg in backend_map.items() + if cfg.type + in { + StorageBackendType.KV_REDIS, + StorageBackendType.KV_SQLITE, + StorageBackendType.KV_POSTGRES, + StorageBackendType.KV_MONGODB, + } + } + sql_backends = { + name + for name, cfg in backend_map.items() + if cfg.type in {StorageBackendType.SQL_SQLITE, StorageBackendType.SQL_POSTGRES} + } + + def _ensure_backend(reference, expected_set, store_name: str) -> None: + if reference is None: + return + backend_name = reference.backend + if backend_name not in backend_map: + raise ValueError( + f"{store_name} references unknown backend '{backend_name}'. " + f"Available backends: {sorted(backend_map)}" + ) + if backend_name not in expected_set: + raise ValueError( + f"{store_name} references backend '{backend_name}' of type " + f"'{backend_map[backend_name].type.value}', but a backend of type " + f"{'kv_*' if expected_set is kv_backends else 'sql_*'} is required." + ) + + _ensure_backend(stores.metadata, kv_backends, "storage.stores.metadata") + _ensure_backend(stores.inference, sql_backends, "storage.stores.inference") + _ensure_backend(stores.conversations, sql_backends, "storage.stores.conversations") + _ensure_backend(stores.responses, sql_backends, "storage.stores.responses") + return self + class BuildConfig(BaseModel): version: int = LLAMA_STACK_BUILD_CONFIG_VERSION diff --git a/llama_stack/core/distribution.py b/llama_stack/core/distribution.py index 0e1f672c3..82cbcf984 100644 --- a/llama_stack/core/distribution.py +++ b/llama_stack/core/distribution.py @@ -63,6 +63,10 @@ def builtin_automatically_routed_apis() -> list[AutoRoutedApiInfo]: routing_table_api=Api.tool_groups, router_api=Api.tool_runtime, ), + AutoRoutedApiInfo( + routing_table_api=Api.vector_stores, + router_api=Api.vector_io, + ), ] diff --git a/llama_stack/core/library_client.py b/llama_stack/core/library_client.py index 1179075cd..c64b9a391 100644 --- a/llama_stack/core/library_client.py +++ b/llama_stack/core/library_client.py @@ -47,7 +47,7 @@ from llama_stack.core.stack import ( from llama_stack.core.utils.config import redact_sensitive_fields from llama_stack.core.utils.context import preserve_contexts_async_generator from llama_stack.core.utils.exec import in_notebook -from llama_stack.log import get_logger +from llama_stack.log import get_logger, setup_logging from llama_stack.providers.utils.telemetry.tracing import CURRENT_TRACE_CONTEXT, end_trace, setup_logger, start_trace from llama_stack.strong_typing.inspection import is_unwrapped_body_param @@ -200,6 +200,9 @@ class AsyncLlamaStackAsLibraryClient(AsyncLlamaStackClient): skip_logger_removal: bool = False, ): super().__init__() + # Initialize logging from environment variables first + setup_logging() + # when using the library client, we should not log to console since many # of our logs are intended for server-side usage if sinks_from_env := os.environ.get("TELEMETRY_SINKS", None): @@ -278,7 +281,7 @@ class AsyncLlamaStackAsLibraryClient(AsyncLlamaStackClient): else: prefix = "!" if in_notebook() else "" cprint( - f"Please run:\n\n{prefix}llama stack build --distro {self.config_path_or_distro_name} --image-type venv\n\n", + f"Please run:\n\n{prefix}llama stack list-deps {self.config_path_or_distro_name} | xargs -L1 uv pip install\n\n", "yellow", file=sys.stderr, ) diff --git a/llama_stack/core/prompts/prompts.py b/llama_stack/core/prompts/prompts.py index 26e8f5cef..856397ca5 100644 --- a/llama_stack/core/prompts/prompts.py +++ b/llama_stack/core/prompts/prompts.py @@ -11,9 +11,8 @@ from pydantic import BaseModel from llama_stack.apis.prompts import ListPromptsResponse, Prompt, Prompts from llama_stack.core.datatypes import StackRunConfig -from llama_stack.core.utils.config_dirs import DISTRIBS_BASE_DIR +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.providers.utils.kvstore import KVStore, kvstore_impl -from llama_stack.providers.utils.kvstore.config import SqliteKVStoreConfig class PromptServiceConfig(BaseModel): @@ -41,10 +40,12 @@ class PromptServiceImpl(Prompts): self.kvstore: KVStore async def initialize(self) -> None: - kvstore_config = SqliteKVStoreConfig( - db_path=(DISTRIBS_BASE_DIR / self.config.run_config.image_name / "prompts.db").as_posix() - ) - self.kvstore = await kvstore_impl(kvstore_config) + # Use metadata store backend with prompts-specific namespace + metadata_ref = self.config.run_config.storage.stores.metadata + if not metadata_ref: + raise ValueError("storage.stores.metadata must be configured in run config") + prompts_ref = KVStoreReference(namespace="prompts", backend=metadata_ref.backend) + self.kvstore = await kvstore_impl(prompts_ref) def _get_default_key(self, prompt_id: str) -> str: """Get the KVStore key that stores the default version number.""" diff --git a/llama_stack/core/resolver.py b/llama_stack/core/resolver.py index acd459f99..0b63815ea 100644 --- a/llama_stack/core/resolver.py +++ b/llama_stack/core/resolver.py @@ -30,6 +30,7 @@ from llama_stack.apis.shields import Shields from llama_stack.apis.telemetry import Telemetry from llama_stack.apis.tools import ToolGroups, ToolRuntime from llama_stack.apis.vector_io import VectorIO +from llama_stack.apis.vector_stores import VectorStore from llama_stack.apis.version import LLAMA_STACK_API_V1ALPHA from llama_stack.core.client import get_client_impl from llama_stack.core.datatypes import ( @@ -81,6 +82,7 @@ def api_protocol_map(external_apis: dict[Api, ExternalApiSpec] | None = None) -> Api.inspect: Inspect, Api.batches: Batches, Api.vector_io: VectorIO, + Api.vector_stores: VectorStore, Api.models: Models, Api.safety: Safety, Api.shields: Shields, diff --git a/llama_stack/core/routers/__init__.py b/llama_stack/core/routers/__init__.py index 4463d2460..20c17e59d 100644 --- a/llama_stack/core/routers/__init__.py +++ b/llama_stack/core/routers/__init__.py @@ -6,7 +6,10 @@ from typing import Any -from llama_stack.core.datatypes import AccessRule, RoutedProtocol +from llama_stack.core.datatypes import ( + AccessRule, + RoutedProtocol, +) from llama_stack.core.stack import StackRunConfig from llama_stack.core.store import DistributionRegistry from llama_stack.providers.datatypes import Api, RoutingTable @@ -26,6 +29,7 @@ async def get_routing_table_impl( from ..routing_tables.scoring_functions import ScoringFunctionsRoutingTable from ..routing_tables.shields import ShieldsRoutingTable from ..routing_tables.toolgroups import ToolGroupsRoutingTable + from ..routing_tables.vector_stores import VectorStoresRoutingTable api_to_tables = { "models": ModelsRoutingTable, @@ -34,6 +38,7 @@ async def get_routing_table_impl( "scoring_functions": ScoringFunctionsRoutingTable, "benchmarks": BenchmarksRoutingTable, "tool_groups": ToolGroupsRoutingTable, + "vector_stores": VectorStoresRoutingTable, } if api.value not in api_to_tables: @@ -76,14 +81,21 @@ async def get_auto_router_impl( api_to_dep_impl[dep_name] = deps[dep_api] # TODO: move pass configs to routers instead - if api == Api.inference and run_config.inference_store: + if api == Api.inference: + inference_ref = run_config.storage.stores.inference + if not inference_ref: + raise ValueError("storage.stores.inference must be configured in run config") + inference_store = InferenceStore( - config=run_config.inference_store, + reference=inference_ref, policy=policy, ) await inference_store.initialize() api_to_dep_impl["store"] = inference_store + elif api == Api.vector_io: + api_to_dep_impl["vector_stores_config"] = run_config.vector_stores + impl = api_to_routers[api.value](routing_table, **api_to_dep_impl) await impl.initialize() return impl diff --git a/llama_stack/core/routers/tool_runtime.py b/llama_stack/core/routers/tool_runtime.py index ad82293e5..be4c13905 100644 --- a/llama_stack/core/routers/tool_runtime.py +++ b/llama_stack/core/routers/tool_runtime.py @@ -37,24 +37,24 @@ class ToolRuntimeRouter(ToolRuntime): async def query( self, content: InterleavedContent, - vector_db_ids: list[str], + vector_store_ids: list[str], query_config: RAGQueryConfig | None = None, ) -> RAGQueryResult: - logger.debug(f"ToolRuntimeRouter.RagToolImpl.query: {vector_db_ids}") + logger.debug(f"ToolRuntimeRouter.RagToolImpl.query: {vector_store_ids}") provider = await self.routing_table.get_provider_impl("knowledge_search") - return await provider.query(content, vector_db_ids, query_config) + return await provider.query(content, vector_store_ids, query_config) async def insert( self, documents: list[RAGDocument], - vector_db_id: str, + vector_store_id: str, chunk_size_in_tokens: int = 512, ) -> None: logger.debug( - f"ToolRuntimeRouter.RagToolImpl.insert: {vector_db_id}, {len(documents)} documents, chunk_size={chunk_size_in_tokens}" + f"ToolRuntimeRouter.RagToolImpl.insert: {vector_store_id}, {len(documents)} documents, chunk_size={chunk_size_in_tokens}" ) provider = await self.routing_table.get_provider_impl("insert_into_memory") - return await provider.insert(documents, vector_db_id, chunk_size_in_tokens) + return await provider.insert(documents, vector_store_id, chunk_size_in_tokens) def __init__( self, diff --git a/llama_stack/core/routers/vector_io.py b/llama_stack/core/routers/vector_io.py index f4e871a40..2b1701dc2 100644 --- a/llama_stack/core/routers/vector_io.py +++ b/llama_stack/core/routers/vector_io.py @@ -31,6 +31,7 @@ from llama_stack.apis.vector_io import ( VectorStoreObject, VectorStoreSearchResponsePage, ) +from llama_stack.core.datatypes import VectorStoresConfig from llama_stack.log import get_logger from llama_stack.providers.datatypes import HealthResponse, HealthStatus, RoutingTable @@ -43,9 +44,11 @@ class VectorIORouter(VectorIO): def __init__( self, routing_table: RoutingTable, + vector_stores_config: VectorStoresConfig | None = None, ) -> None: logger.debug("Initializing VectorIORouter") self.routing_table = routing_table + self.vector_stores_config = vector_stores_config async def initialize(self) -> None: logger.debug("VectorIORouter.initialize") @@ -68,25 +71,6 @@ class VectorIORouter(VectorIO): raise ValueError(f"Embedding model '{embedding_model_id}' not found or not an embedding model") - async def register_vector_db( - self, - vector_db_id: str, - embedding_model: str, - embedding_dimension: int | None = 384, - provider_id: str | None = None, - vector_db_name: str | None = None, - provider_vector_db_id: str | None = None, - ) -> None: - logger.debug(f"VectorIORouter.register_vector_db: {vector_db_id}, {embedding_model}") - await self.routing_table.register_vector_db( - vector_db_id, - embedding_model, - embedding_dimension, - provider_id, - vector_db_name, - provider_vector_db_id, - ) - async def insert_chunks( self, vector_db_id: str, @@ -122,6 +106,17 @@ class VectorIORouter(VectorIO): embedding_dimension = extra.get("embedding_dimension") provider_id = extra.get("provider_id") + # Use default embedding model if not specified + if ( + embedding_model is None + and self.vector_stores_config + and self.vector_stores_config.default_embedding_model is not None + ): + # Construct the full model ID with provider prefix + embedding_provider_id = self.vector_stores_config.default_embedding_model.provider_id + model_id = self.vector_stores_config.default_embedding_model.model_id + embedding_model = f"{embedding_provider_id}/{model_id}" + if embedding_model is not None and embedding_dimension is None: embedding_dimension = await self._get_embedding_model_dimension(embedding_model) @@ -132,28 +127,41 @@ class VectorIORouter(VectorIO): raise ValueError("No vector_io providers available") if num_providers > 1: available_providers = list(self.routing_table.impls_by_provider_id.keys()) - raise ValueError( - f"Multiple vector_io providers available. Please specify provider_id in extra_body. " - f"Available providers: {available_providers}" - ) - provider_id = list(self.routing_table.impls_by_provider_id.keys())[0] + # Use default configured provider + if self.vector_stores_config and self.vector_stores_config.default_provider_id: + default_provider = self.vector_stores_config.default_provider_id + if default_provider in available_providers: + provider_id = default_provider + logger.debug(f"Using configured default vector store provider: {provider_id}") + else: + raise ValueError( + f"Configured default vector store provider '{default_provider}' not found. " + f"Available providers: {available_providers}" + ) + else: + raise ValueError( + f"Multiple vector_io providers available. Please specify provider_id in extra_body. " + f"Available providers: {available_providers}" + ) + else: + provider_id = list(self.routing_table.impls_by_provider_id.keys())[0] - vector_db_id = f"vs_{uuid.uuid4()}" - registered_vector_db = await self.routing_table.register_vector_db( - vector_db_id=vector_db_id, + vector_store_id = f"vs_{uuid.uuid4()}" + registered_vector_store = await self.routing_table.register_vector_store( + vector_store_id=vector_store_id, embedding_model=embedding_model, embedding_dimension=embedding_dimension, provider_id=provider_id, - provider_vector_db_id=vector_db_id, - vector_db_name=params.name, + provider_vector_store_id=vector_store_id, + vector_store_name=params.name, ) - provider = await self.routing_table.get_provider_impl(registered_vector_db.identifier) + provider = await self.routing_table.get_provider_impl(registered_vector_store.identifier) - # Update model_extra with registered values so provider uses the already-registered vector_db + # Update model_extra with registered values so provider uses the already-registered vector_store if params.model_extra is None: params.model_extra = {} - params.model_extra["provider_vector_db_id"] = registered_vector_db.provider_resource_id - params.model_extra["provider_id"] = registered_vector_db.provider_id + params.model_extra["provider_vector_store_id"] = registered_vector_store.provider_resource_id + params.model_extra["provider_id"] = registered_vector_store.provider_id if embedding_model is not None: params.model_extra["embedding_model"] = embedding_model if embedding_dimension is not None: @@ -171,15 +179,15 @@ class VectorIORouter(VectorIO): logger.debug(f"VectorIORouter.openai_list_vector_stores: limit={limit}") # Route to default provider for now - could aggregate from all providers in the future # call retrieve on each vector dbs to get list of vector stores - vector_dbs = await self.routing_table.get_all_with_type("vector_db") + vector_stores = await self.routing_table.get_all_with_type("vector_store") all_stores = [] - for vector_db in vector_dbs: + for vector_store in vector_stores: try: - provider = await self.routing_table.get_provider_impl(vector_db.identifier) - vector_store = await provider.openai_retrieve_vector_store(vector_db.identifier) + provider = await self.routing_table.get_provider_impl(vector_store.identifier) + vector_store = await provider.openai_retrieve_vector_store(vector_store.identifier) all_stores.append(vector_store) except Exception as e: - logger.error(f"Error retrieving vector store {vector_db.identifier}: {e}") + logger.error(f"Error retrieving vector store {vector_store.identifier}: {e}") continue # Sort by created_at @@ -243,8 +251,7 @@ class VectorIORouter(VectorIO): vector_store_id: str, ) -> VectorStoreDeleteResponse: logger.debug(f"VectorIORouter.openai_delete_vector_store: {vector_store_id}") - provider = await self.routing_table.get_provider_impl(vector_store_id) - return await provider.openai_delete_vector_store(vector_store_id) + return await self.routing_table.openai_delete_vector_store(vector_store_id) async def openai_search_vector_store( self, diff --git a/llama_stack/core/routing_tables/common.py b/llama_stack/core/routing_tables/common.py index 8df0a89a9..d6faf93c5 100644 --- a/llama_stack/core/routing_tables/common.py +++ b/llama_stack/core/routing_tables/common.py @@ -41,7 +41,7 @@ async def register_object_with_provider(obj: RoutableObject, p: Any) -> Routable elif api == Api.safety: return await p.register_shield(obj) elif api == Api.vector_io: - return await p.register_vector_db(obj) + return await p.register_vector_store(obj) elif api == Api.datasetio: return await p.register_dataset(obj) elif api == Api.scoring: @@ -57,7 +57,7 @@ async def register_object_with_provider(obj: RoutableObject, p: Any) -> Routable async def unregister_object_from_provider(obj: RoutableObject, p: Any) -> None: api = get_impl_api(p) if api == Api.vector_io: - return await p.unregister_vector_db(obj.identifier) + return await p.unregister_vector_store(obj.identifier) elif api == Api.inference: return await p.unregister_model(obj.identifier) elif api == Api.safety: @@ -108,7 +108,7 @@ class CommonRoutingTableImpl(RoutingTable): elif api == Api.safety: p.shield_store = self elif api == Api.vector_io: - p.vector_db_store = self + p.vector_store_store = self elif api == Api.datasetio: p.dataset_store = self elif api == Api.scoring: @@ -134,12 +134,15 @@ class CommonRoutingTableImpl(RoutingTable): from .scoring_functions import ScoringFunctionsRoutingTable from .shields import ShieldsRoutingTable from .toolgroups import ToolGroupsRoutingTable + from .vector_stores import VectorStoresRoutingTable def apiname_object(): if isinstance(self, ModelsRoutingTable): return ("Inference", "model") elif isinstance(self, ShieldsRoutingTable): return ("Safety", "shield") + elif isinstance(self, VectorStoresRoutingTable): + return ("VectorIO", "vector_store") elif isinstance(self, DatasetsRoutingTable): return ("DatasetIO", "dataset") elif isinstance(self, ScoringFunctionsRoutingTable): diff --git a/llama_stack/core/routing_tables/vector_stores.py b/llama_stack/core/routing_tables/vector_stores.py new file mode 100644 index 000000000..c6c80a01e --- /dev/null +++ b/llama_stack/core/routing_tables/vector_stores.py @@ -0,0 +1,292 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +from typing import Any + +from llama_stack.apis.common.errors import ModelNotFoundError, ModelTypeError +from llama_stack.apis.models import ModelType +from llama_stack.apis.resource import ResourceType + +# Removed VectorStores import to avoid exposing public API +from llama_stack.apis.vector_io.vector_io import ( + SearchRankingOptions, + VectorStoreChunkingStrategy, + VectorStoreDeleteResponse, + VectorStoreFileContentsResponse, + VectorStoreFileDeleteResponse, + VectorStoreFileObject, + VectorStoreFileStatus, + VectorStoreObject, + VectorStoreSearchResponsePage, +) +from llama_stack.core.datatypes import ( + VectorStoreWithOwner, +) +from llama_stack.log import get_logger + +from .common import CommonRoutingTableImpl, lookup_model + +logger = get_logger(name=__name__, category="core::routing_tables") + + +class VectorStoresRoutingTable(CommonRoutingTableImpl): + """Internal routing table for vector_store operations. + + Does not inherit from VectorStores to avoid exposing public API endpoints. + Only provides internal routing functionality for VectorIORouter. + """ + + # Internal methods only - no public API exposure + + async def register_vector_store( + self, + vector_store_id: str, + embedding_model: str, + embedding_dimension: int | None = 384, + provider_id: str | None = None, + provider_vector_store_id: str | None = None, + vector_store_name: str | None = None, + ) -> Any: + if provider_id is None: + if len(self.impls_by_provider_id) > 0: + provider_id = list(self.impls_by_provider_id.keys())[0] + if len(self.impls_by_provider_id) > 1: + logger.warning( + f"No provider specified and multiple providers available. Arbitrarily selected the first provider {provider_id}." + ) + else: + raise ValueError("No provider available. Please configure a vector_io provider.") + model = await lookup_model(self, embedding_model) + if model is None: + raise ModelNotFoundError(embedding_model) + if model.model_type != ModelType.embedding: + raise ModelTypeError(embedding_model, model.model_type, ModelType.embedding) + + vector_store = VectorStoreWithOwner( + identifier=vector_store_id, + type=ResourceType.vector_store.value, + provider_id=provider_id, + provider_resource_id=provider_vector_store_id, + embedding_model=embedding_model, + embedding_dimension=embedding_dimension, + vector_store_name=vector_store_name, + ) + await self.register_object(vector_store) + return vector_store + + async def openai_retrieve_vector_store( + self, + vector_store_id: str, + ) -> VectorStoreObject: + await self.assert_action_allowed("read", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_retrieve_vector_store(vector_store_id) + + async def openai_update_vector_store( + self, + vector_store_id: str, + name: str | None = None, + expires_after: dict[str, Any] | None = None, + metadata: dict[str, Any] | None = None, + ) -> VectorStoreObject: + await self.assert_action_allowed("update", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_update_vector_store( + vector_store_id=vector_store_id, + name=name, + expires_after=expires_after, + metadata=metadata, + ) + + async def openai_delete_vector_store( + self, + vector_store_id: str, + ) -> VectorStoreDeleteResponse: + await self.assert_action_allowed("delete", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + result = await provider.openai_delete_vector_store(vector_store_id) + await self.unregister_vector_store(vector_store_id) + return result + + async def unregister_vector_store(self, vector_store_id: str) -> None: + """Remove the vector store from the routing table registry.""" + try: + vector_store_obj = await self.get_object_by_identifier("vector_store", vector_store_id) + if vector_store_obj: + await self.unregister_object(vector_store_obj) + except Exception as e: + # Log the error but don't fail the operation + logger.warning(f"Failed to unregister vector store {vector_store_id} from routing table: {e}") + + async def openai_search_vector_store( + self, + vector_store_id: str, + query: str | list[str], + filters: dict[str, Any] | None = None, + max_num_results: int | None = 10, + ranking_options: SearchRankingOptions | None = None, + rewrite_query: bool | None = False, + search_mode: str | None = "vector", + ) -> VectorStoreSearchResponsePage: + await self.assert_action_allowed("read", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_search_vector_store( + vector_store_id=vector_store_id, + query=query, + filters=filters, + max_num_results=max_num_results, + ranking_options=ranking_options, + rewrite_query=rewrite_query, + search_mode=search_mode, + ) + + async def openai_attach_file_to_vector_store( + self, + vector_store_id: str, + file_id: str, + attributes: dict[str, Any] | None = None, + chunking_strategy: VectorStoreChunkingStrategy | None = None, + ) -> VectorStoreFileObject: + await self.assert_action_allowed("update", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_attach_file_to_vector_store( + vector_store_id=vector_store_id, + file_id=file_id, + attributes=attributes, + chunking_strategy=chunking_strategy, + ) + + async def openai_list_files_in_vector_store( + self, + vector_store_id: str, + limit: int | None = 20, + order: str | None = "desc", + after: str | None = None, + before: str | None = None, + filter: VectorStoreFileStatus | None = None, + ) -> list[VectorStoreFileObject]: + await self.assert_action_allowed("read", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_list_files_in_vector_store( + vector_store_id=vector_store_id, + limit=limit, + order=order, + after=after, + before=before, + filter=filter, + ) + + async def openai_retrieve_vector_store_file( + self, + vector_store_id: str, + file_id: str, + ) -> VectorStoreFileObject: + await self.assert_action_allowed("read", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_retrieve_vector_store_file( + vector_store_id=vector_store_id, + file_id=file_id, + ) + + async def openai_retrieve_vector_store_file_contents( + self, + vector_store_id: str, + file_id: str, + ) -> VectorStoreFileContentsResponse: + await self.assert_action_allowed("read", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_retrieve_vector_store_file_contents( + vector_store_id=vector_store_id, + file_id=file_id, + ) + + async def openai_update_vector_store_file( + self, + vector_store_id: str, + file_id: str, + attributes: dict[str, Any], + ) -> VectorStoreFileObject: + await self.assert_action_allowed("update", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_update_vector_store_file( + vector_store_id=vector_store_id, + file_id=file_id, + attributes=attributes, + ) + + async def openai_delete_vector_store_file( + self, + vector_store_id: str, + file_id: str, + ) -> VectorStoreFileDeleteResponse: + await self.assert_action_allowed("delete", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_delete_vector_store_file( + vector_store_id=vector_store_id, + file_id=file_id, + ) + + async def openai_create_vector_store_file_batch( + self, + vector_store_id: str, + file_ids: list[str], + attributes: dict[str, Any] | None = None, + chunking_strategy: Any | None = None, + ): + await self.assert_action_allowed("update", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_create_vector_store_file_batch( + vector_store_id=vector_store_id, + file_ids=file_ids, + attributes=attributes, + chunking_strategy=chunking_strategy, + ) + + async def openai_retrieve_vector_store_file_batch( + self, + batch_id: str, + vector_store_id: str, + ): + await self.assert_action_allowed("read", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_retrieve_vector_store_file_batch( + batch_id=batch_id, + vector_store_id=vector_store_id, + ) + + async def openai_list_files_in_vector_store_file_batch( + self, + batch_id: str, + vector_store_id: str, + after: str | None = None, + before: str | None = None, + filter: str | None = None, + limit: int | None = 20, + order: str | None = "desc", + ): + await self.assert_action_allowed("read", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_list_files_in_vector_store_file_batch( + batch_id=batch_id, + vector_store_id=vector_store_id, + after=after, + before=before, + filter=filter, + limit=limit, + order=order, + ) + + async def openai_cancel_vector_store_file_batch( + self, + batch_id: str, + vector_store_id: str, + ): + await self.assert_action_allowed("update", "vector_store", vector_store_id) + provider = await self.get_provider_impl(vector_store_id) + return await provider.openai_cancel_vector_store_file_batch( + batch_id=batch_id, + vector_store_id=vector_store_id, + ) diff --git a/llama_stack/core/server/auth_providers.py b/llama_stack/core/server/auth_providers.py index 05a21c8d4..0fe5f1558 100644 --- a/llama_stack/core/server/auth_providers.py +++ b/llama_stack/core/server/auth_providers.py @@ -72,13 +72,30 @@ class AuthProvider(ABC): def get_attributes_from_claims(claims: dict[str, str], mapping: dict[str, str]) -> dict[str, list[str]]: attributes: dict[str, list[str]] = {} for claim_key, attribute_key in mapping.items(): - if claim_key not in claims: + # First try dot notation for nested traversal (e.g., "resource_access.llamastack.roles") + # Then fall back to literal key with dots (e.g., "my.dotted.key") + claim: object = claims + keys = claim_key.split(".") + for key in keys: + if isinstance(claim, dict) and key in claim: + claim = claim[key] + else: + claim = None + break + + if claim is None and claim_key in claims: + # Fall back to checking if claim_key exists as a literal key + claim = claims[claim_key] + + if claim is None: continue - claim = claims[claim_key] + if isinstance(claim, list): values = claim - else: + elif isinstance(claim, str): values = claim.split() + else: + continue if attribute_key in attributes: attributes[attribute_key].extend(values) diff --git a/llama_stack/core/server/quota.py b/llama_stack/core/server/quota.py index 693f224c3..689f0e4c3 100644 --- a/llama_stack/core/server/quota.py +++ b/llama_stack/core/server/quota.py @@ -10,10 +10,10 @@ from datetime import UTC, datetime, timedelta from starlette.types import ASGIApp, Receive, Scope, Send +from llama_stack.core.storage.datatypes import KVStoreReference, StorageBackendType from llama_stack.log import get_logger from llama_stack.providers.utils.kvstore.api import KVStore -from llama_stack.providers.utils.kvstore.config import KVStoreConfig, SqliteKVStoreConfig -from llama_stack.providers.utils.kvstore.kvstore import kvstore_impl +from llama_stack.providers.utils.kvstore.kvstore import _KVSTORE_BACKENDS, kvstore_impl logger = get_logger(name=__name__, category="core::server") @@ -33,7 +33,7 @@ class QuotaMiddleware: def __init__( self, app: ASGIApp, - kv_config: KVStoreConfig, + kv_config: KVStoreReference, anonymous_max_requests: int, authenticated_max_requests: int, window_seconds: int = 86400, @@ -45,15 +45,15 @@ class QuotaMiddleware: self.authenticated_max_requests = authenticated_max_requests self.window_seconds = window_seconds - if isinstance(self.kv_config, SqliteKVStoreConfig): - logger.warning( - "QuotaMiddleware: Using SQLite backend. Expiry/TTL is not enforced; cleanup is manual. " - f"window_seconds={self.window_seconds}" - ) - async def _get_kv(self) -> KVStore: if self.kv is None: self.kv = await kvstore_impl(self.kv_config) + backend_config = _KVSTORE_BACKENDS.get(self.kv_config.backend) + if backend_config and backend_config.type == StorageBackendType.KV_SQLITE: + logger.warning( + "QuotaMiddleware: Using SQLite backend. Expiry/TTL is not enforced; cleanup is manual. " + f"window_seconds={self.window_seconds}" + ) return self.kv async def __call__(self, scope: Scope, receive: Receive, send: Send): diff --git a/llama_stack/core/server/server.py b/llama_stack/core/server/server.py index db7584b01..dd21a72f9 100644 --- a/llama_stack/core/server/server.py +++ b/llama_stack/core/server/server.py @@ -56,7 +56,7 @@ from llama_stack.core.stack import ( from llama_stack.core.utils.config import redact_sensitive_fields from llama_stack.core.utils.config_resolution import Mode, resolve_config_or_distro from llama_stack.core.utils.context import preserve_contexts_async_generator -from llama_stack.log import get_logger +from llama_stack.log import get_logger, setup_logging from llama_stack.providers.datatypes import Api from llama_stack.providers.inline.telemetry.meta_reference.config import TelemetryConfig from llama_stack.providers.inline.telemetry.meta_reference.telemetry import ( @@ -374,6 +374,9 @@ def create_app() -> StackApp: Returns: Configured StackApp instance. """ + # Initialize logging from environment variables first + setup_logging() + config_file = os.getenv("LLAMA_STACK_CONFIG") if config_file is None: raise ValueError("LLAMA_STACK_CONFIG environment variable is required") diff --git a/llama_stack/core/stack.py b/llama_stack/core/stack.py index 733b55262..4cf1d072d 100644 --- a/llama_stack/core/stack.py +++ b/llama_stack/core/stack.py @@ -35,13 +35,23 @@ from llama_stack.apis.telemetry import Telemetry from llama_stack.apis.tools import RAGToolRuntime, ToolGroups, ToolRuntime from llama_stack.apis.vector_io import VectorIO from llama_stack.core.conversations.conversations import ConversationServiceConfig, ConversationServiceImpl -from llama_stack.core.datatypes import Provider, StackRunConfig +from llama_stack.core.datatypes import Provider, StackRunConfig, VectorStoresConfig from llama_stack.core.distribution import get_provider_registry from llama_stack.core.inspect import DistributionInspectConfig, DistributionInspectImpl from llama_stack.core.prompts.prompts import PromptServiceConfig, PromptServiceImpl from llama_stack.core.providers import ProviderImpl, ProviderImplConfig from llama_stack.core.resolver import ProviderRegistry, resolve_impls from llama_stack.core.routing_tables.common import CommonRoutingTableImpl +from llama_stack.core.storage.datatypes import ( + InferenceStoreReference, + KVStoreReference, + ServerStoresConfig, + SqliteKVStoreConfig, + SqliteSqlStoreConfig, + SqlStoreReference, + StorageBackendConfig, + StorageConfig, +) from llama_stack.core.store.registry import create_dist_registry from llama_stack.core.utils.dynamic import instantiate_class_type from llama_stack.log import get_logger @@ -98,33 +108,9 @@ REGISTRY_REFRESH_TASK = None TEST_RECORDING_CONTEXT = None -async def validate_default_embedding_model(impls: dict[Api, Any]): - """Validate that at most one embedding model is marked as default.""" - if Api.models not in impls: - return - - models_impl = impls[Api.models] - response = await models_impl.list_models() - models_list = response.data if hasattr(response, "data") else response - - default_embedding_models = [] - for model in models_list: - if model.model_type == "embedding" and model.metadata.get("default_configured") is True: - default_embedding_models.append(model.identifier) - - if len(default_embedding_models) > 1: - raise ValueError( - f"Multiple embedding models marked as default_configured=True: {default_embedding_models}. " - "Only one embedding model can be marked as default." - ) - - if default_embedding_models: - logger.info(f"Default embedding model configured: {default_embedding_models[0]}") - - async def register_resources(run_config: StackRunConfig, impls: dict[Api, Any]): for rsrc, api, register_method, list_method in RESOURCES: - objects = getattr(run_config, rsrc) + objects = getattr(run_config.registered_resources, rsrc) if api not in impls: continue @@ -152,7 +138,41 @@ async def register_resources(run_config: StackRunConfig, impls: dict[Api, Any]): f"{rsrc.capitalize()}: {obj.identifier} served by {obj.provider_id}", ) - await validate_default_embedding_model(impls) + +async def validate_vector_stores_config(vector_stores_config: VectorStoresConfig | None, impls: dict[Api, Any]): + """Validate vector stores configuration.""" + if vector_stores_config is None: + return + + default_embedding_model = vector_stores_config.default_embedding_model + if default_embedding_model is None: + return + + provider_id = default_embedding_model.provider_id + model_id = default_embedding_model.model_id + default_model_id = f"{provider_id}/{model_id}" + + if Api.models not in impls: + raise ValueError(f"Models API is not available but vector_stores config requires model '{default_model_id}'") + + models_impl = impls[Api.models] + response = await models_impl.list_models() + models_list = {m.identifier: m for m in response.data if m.model_type == "embedding"} + + default_model = models_list.get(default_model_id) + if default_model is None: + raise ValueError(f"Embedding model '{default_model_id}' not found. Available embedding models: {models_list}") + + embedding_dimension = default_model.metadata.get("embedding_dimension") + if embedding_dimension is None: + raise ValueError(f"Embedding model '{default_model_id}' is missing 'embedding_dimension' in metadata") + + try: + int(embedding_dimension) + except ValueError as err: + raise ValueError(f"Embedding dimension '{embedding_dimension}' cannot be converted to an integer") from err + + logger.debug(f"Validated default embedding model: {default_model_id} (dimension: {embedding_dimension})") class EnvVarError(Exception): @@ -329,6 +349,25 @@ def add_internal_implementations(impls: dict[Api, Any], run_config: StackRunConf impls[Api.conversations] = conversations_impl +def _initialize_storage(run_config: StackRunConfig): + kv_backends: dict[str, StorageBackendConfig] = {} + sql_backends: dict[str, StorageBackendConfig] = {} + for backend_name, backend_config in run_config.storage.backends.items(): + type = backend_config.type.value + if type.startswith("kv_"): + kv_backends[backend_name] = backend_config + elif type.startswith("sql_"): + sql_backends[backend_name] = backend_config + else: + raise ValueError(f"Unknown storage backend type: {type}") + + from llama_stack.providers.utils.kvstore.kvstore import register_kvstore_backends + from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends + + register_kvstore_backends(kv_backends) + register_sqlstore_backends(sql_backends) + + class Stack: def __init__(self, run_config: StackRunConfig, provider_registry: ProviderRegistry | None = None): self.run_config = run_config @@ -347,7 +386,11 @@ class Stack: TEST_RECORDING_CONTEXT.__enter__() logger.info(f"API recording enabled: mode={os.environ.get('LLAMA_STACK_TEST_INFERENCE_MODE')}") - dist_registry, _ = await create_dist_registry(self.run_config.metadata_store, self.run_config.image_name) + _initialize_storage(self.run_config) + stores = self.run_config.storage.stores + if not stores.metadata: + raise ValueError("storage.stores.metadata must be configured with a kv_* backend") + dist_registry, _ = await create_dist_registry(stores.metadata, self.run_config.image_name) policy = self.run_config.server.auth.access_policy if self.run_config.server.auth else [] internal_impls = {} @@ -367,8 +410,8 @@ class Stack: await impls[Api.conversations].initialize() await register_resources(self.run_config, impls) - await refresh_registry_once(impls) + await validate_vector_stores_config(self.run_config.vector_stores, impls) self.impls = impls def create_registry_refresh_task(self): @@ -488,5 +531,16 @@ def run_config_from_adhoc_config_spec( image_name="distro-test", apis=list(provider_configs_by_api.keys()), providers=provider_configs_by_api, + storage=StorageConfig( + backends={ + "kv_default": SqliteKVStoreConfig(db_path=f"{distro_dir}/kvstore.db"), + "sql_default": SqliteSqlStoreConfig(db_path=f"{distro_dir}/sql_store.db"), + }, + stores=ServerStoresConfig( + metadata=KVStoreReference(backend="kv_default", namespace="registry"), + inference=InferenceStoreReference(backend="sql_default", table_name="inference_store"), + conversations=SqlStoreReference(backend="sql_default", table_name="openai_conversations"), + ), + ), ) return config diff --git a/llama_stack/apis/vector_dbs/__init__.py b/llama_stack/core/storage/__init__.py similarity index 88% rename from llama_stack/apis/vector_dbs/__init__.py rename to llama_stack/core/storage/__init__.py index af34ba9d4..756f351d8 100644 --- a/llama_stack/apis/vector_dbs/__init__.py +++ b/llama_stack/core/storage/__init__.py @@ -3,5 +3,3 @@ # # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. - -from .vector_dbs import * diff --git a/llama_stack/core/storage/datatypes.py b/llama_stack/core/storage/datatypes.py new file mode 100644 index 000000000..9df170e10 --- /dev/null +++ b/llama_stack/core/storage/datatypes.py @@ -0,0 +1,283 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +import re +from abc import abstractmethod +from enum import StrEnum +from pathlib import Path +from typing import Annotated, Literal + +from pydantic import BaseModel, Field, field_validator + + +class StorageBackendType(StrEnum): + KV_REDIS = "kv_redis" + KV_SQLITE = "kv_sqlite" + KV_POSTGRES = "kv_postgres" + KV_MONGODB = "kv_mongodb" + SQL_SQLITE = "sql_sqlite" + SQL_POSTGRES = "sql_postgres" + + +class CommonConfig(BaseModel): + namespace: str | None = Field( + default=None, + description="All keys will be prefixed with this namespace", + ) + + +class RedisKVStoreConfig(CommonConfig): + type: Literal[StorageBackendType.KV_REDIS] = StorageBackendType.KV_REDIS + host: str = "localhost" + port: int = 6379 + + @property + def url(self) -> str: + return f"redis://{self.host}:{self.port}" + + @classmethod + def pip_packages(cls) -> list[str]: + return ["redis"] + + @classmethod + def sample_run_config(cls): + return { + "type": StorageBackendType.KV_REDIS.value, + "host": "${env.REDIS_HOST:=localhost}", + "port": "${env.REDIS_PORT:=6379}", + } + + +class SqliteKVStoreConfig(CommonConfig): + type: Literal[StorageBackendType.KV_SQLITE] = StorageBackendType.KV_SQLITE + db_path: str = Field( + description="File path for the sqlite database", + ) + + @classmethod + def pip_packages(cls) -> list[str]: + return ["aiosqlite"] + + @classmethod + def sample_run_config(cls, __distro_dir__: str, db_name: str = "kvstore.db"): + return { + "type": StorageBackendType.KV_SQLITE.value, + "db_path": "${env.SQLITE_STORE_DIR:=" + __distro_dir__ + "}/" + db_name, + } + + +class PostgresKVStoreConfig(CommonConfig): + type: Literal[StorageBackendType.KV_POSTGRES] = StorageBackendType.KV_POSTGRES + host: str = "localhost" + port: int | str = 5432 + db: str = "llamastack" + user: str + password: str | None = None + ssl_mode: str | None = None + ca_cert_path: str | None = None + table_name: str = "llamastack_kvstore" + + @classmethod + def sample_run_config(cls, table_name: str = "llamastack_kvstore", **kwargs): + return { + "type": StorageBackendType.KV_POSTGRES.value, + "host": "${env.POSTGRES_HOST:=localhost}", + "port": "${env.POSTGRES_PORT:=5432}", + "db": "${env.POSTGRES_DB:=llamastack}", + "user": "${env.POSTGRES_USER:=llamastack}", + "password": "${env.POSTGRES_PASSWORD:=llamastack}", + "table_name": "${env.POSTGRES_TABLE_NAME:=" + table_name + "}", + } + + @classmethod + @field_validator("table_name") + def validate_table_name(cls, v: str) -> str: + # PostgreSQL identifiers rules: + # - Must start with a letter or underscore + # - Can contain letters, numbers, and underscores + # - Maximum length is 63 bytes + pattern = r"^[a-zA-Z_][a-zA-Z0-9_]*$" + if not re.match(pattern, v): + raise ValueError( + "Invalid table name. Must start with letter or underscore and contain only letters, numbers, and underscores" + ) + if len(v) > 63: + raise ValueError("Table name must be less than 63 characters") + return v + + @classmethod + def pip_packages(cls) -> list[str]: + return ["psycopg2-binary"] + + +class MongoDBKVStoreConfig(CommonConfig): + type: Literal[StorageBackendType.KV_MONGODB] = StorageBackendType.KV_MONGODB + host: str = "localhost" + port: int = 27017 + db: str = "llamastack" + user: str | None = None + password: str | None = None + collection_name: str = "llamastack_kvstore" + + @classmethod + def pip_packages(cls) -> list[str]: + return ["pymongo"] + + @classmethod + def sample_run_config(cls, collection_name: str = "llamastack_kvstore"): + return { + "type": StorageBackendType.KV_MONGODB.value, + "host": "${env.MONGODB_HOST:=localhost}", + "port": "${env.MONGODB_PORT:=5432}", + "db": "${env.MONGODB_DB}", + "user": "${env.MONGODB_USER}", + "password": "${env.MONGODB_PASSWORD}", + "collection_name": "${env.MONGODB_COLLECTION_NAME:=" + collection_name + "}", + } + + +class SqlAlchemySqlStoreConfig(BaseModel): + @property + @abstractmethod + def engine_str(self) -> str: ... + + # TODO: move this when we have a better way to specify dependencies with internal APIs + @classmethod + def pip_packages(cls) -> list[str]: + return ["sqlalchemy[asyncio]"] + + +class SqliteSqlStoreConfig(SqlAlchemySqlStoreConfig): + type: Literal[StorageBackendType.SQL_SQLITE] = StorageBackendType.SQL_SQLITE + db_path: str = Field( + description="Database path, e.g. ~/.llama/distributions/ollama/sqlstore.db", + ) + + @property + def engine_str(self) -> str: + return "sqlite+aiosqlite:///" + Path(self.db_path).expanduser().as_posix() + + @classmethod + def sample_run_config(cls, __distro_dir__: str, db_name: str = "sqlstore.db"): + return { + "type": StorageBackendType.SQL_SQLITE.value, + "db_path": "${env.SQLITE_STORE_DIR:=" + __distro_dir__ + "}/" + db_name, + } + + @classmethod + def pip_packages(cls) -> list[str]: + return super().pip_packages() + ["aiosqlite"] + + +class PostgresSqlStoreConfig(SqlAlchemySqlStoreConfig): + type: Literal[StorageBackendType.SQL_POSTGRES] = StorageBackendType.SQL_POSTGRES + host: str = "localhost" + port: int | str = 5432 + db: str = "llamastack" + user: str + password: str | None = None + + @property + def engine_str(self) -> str: + return f"postgresql+asyncpg://{self.user}:{self.password}@{self.host}:{self.port}/{self.db}" + + @classmethod + def pip_packages(cls) -> list[str]: + return super().pip_packages() + ["asyncpg"] + + @classmethod + def sample_run_config(cls, **kwargs): + return { + "type": StorageBackendType.SQL_POSTGRES.value, + "host": "${env.POSTGRES_HOST:=localhost}", + "port": "${env.POSTGRES_PORT:=5432}", + "db": "${env.POSTGRES_DB:=llamastack}", + "user": "${env.POSTGRES_USER:=llamastack}", + "password": "${env.POSTGRES_PASSWORD:=llamastack}", + } + + +# reference = (backend_name, table_name) +class SqlStoreReference(BaseModel): + """A reference to a 'SQL-like' persistent store. A table name must be provided.""" + + table_name: str = Field( + description="Name of the table to use for the SqlStore", + ) + + backend: str = Field( + description="Name of backend from storage.backends", + ) + + +# reference = (backend_name, namespace) +class KVStoreReference(BaseModel): + """A reference to a 'key-value' persistent store. A namespace must be provided.""" + + namespace: str = Field( + description="Key prefix for KVStore backends", + ) + + backend: str = Field( + description="Name of backend from storage.backends", + ) + + +StorageBackendConfig = Annotated[ + RedisKVStoreConfig + | SqliteKVStoreConfig + | PostgresKVStoreConfig + | MongoDBKVStoreConfig + | SqliteSqlStoreConfig + | PostgresSqlStoreConfig, + Field(discriminator="type"), +] + + +class InferenceStoreReference(SqlStoreReference): + """Inference store configuration with queue tuning.""" + + max_write_queue_size: int = Field( + default=10000, + description="Max queued writes for inference store", + ) + num_writers: int = Field( + default=4, + description="Number of concurrent background writers", + ) + + +class ResponsesStoreReference(InferenceStoreReference): + """Responses store configuration with queue tuning.""" + + +class ServerStoresConfig(BaseModel): + metadata: KVStoreReference | None = Field( + default=None, + description="Metadata store configuration (uses KV backend)", + ) + inference: InferenceStoreReference | None = Field( + default=None, + description="Inference store configuration (uses SQL backend)", + ) + conversations: SqlStoreReference | None = Field( + default=None, + description="Conversations store configuration (uses SQL backend)", + ) + responses: ResponsesStoreReference | None = Field( + default=None, + description="Responses store configuration (uses SQL backend)", + ) + + +class StorageConfig(BaseModel): + backends: dict[str, StorageBackendConfig] = Field( + description="Named backend configurations (e.g., 'default', 'cache')", + ) + stores: ServerStoresConfig = Field( + default_factory=lambda: ServerStoresConfig(), + description="Named references to storage backends used by the stack core", + ) diff --git a/llama_stack/core/store/registry.py b/llama_stack/core/store/registry.py index 04581bab5..6ff9e575b 100644 --- a/llama_stack/core/store/registry.py +++ b/llama_stack/core/store/registry.py @@ -11,10 +11,9 @@ from typing import Protocol import pydantic from llama_stack.core.datatypes import RoutableObjectWithProvider -from llama_stack.core.utils.config_dirs import DISTRIBS_BASE_DIR +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.log import get_logger from llama_stack.providers.utils.kvstore import KVStore, kvstore_impl -from llama_stack.providers.utils.kvstore.config import KVStoreConfig, SqliteKVStoreConfig logger = get_logger(__name__, category="core::registry") @@ -191,16 +190,10 @@ class CachedDiskDistributionRegistry(DiskDistributionRegistry): async def create_dist_registry( - metadata_store: KVStoreConfig | None, - image_name: str, + metadata_store: KVStoreReference, image_name: str ) -> tuple[CachedDiskDistributionRegistry, KVStore]: # instantiate kvstore for storing and retrieving distribution metadata - if metadata_store: - dist_kvstore = await kvstore_impl(metadata_store) - else: - dist_kvstore = await kvstore_impl( - SqliteKVStoreConfig(db_path=(DISTRIBS_BASE_DIR / image_name / "kvstore.db").as_posix()) - ) + dist_kvstore = await kvstore_impl(metadata_store) dist_registry = CachedDiskDistributionRegistry(dist_kvstore) await dist_registry.initialize() return dist_registry, dist_kvstore diff --git a/llama_stack/core/ui/README.md b/llama_stack/core/ui/README.md index f1d85454b..37f1501c9 100644 --- a/llama_stack/core/ui/README.md +++ b/llama_stack/core/ui/README.md @@ -9,7 +9,7 @@ 1. Start up Llama Stack API server. More details [here](https://llamastack.github.io/latest/getting_started/index.htmll). ``` -llama stack build --distro together --image-type venv +llama stack list-deps together | xargs -L1 uv pip install llama stack run together ``` diff --git a/llama_stack/core/ui/page/playground/tools.py b/llama_stack/core/ui/page/playground/tools.py index 4ee9d2204..16fd464ee 100644 --- a/llama_stack/core/ui/page/playground/tools.py +++ b/llama_stack/core/ui/page/playground/tools.py @@ -32,7 +32,7 @@ def tool_chat_page(): tool_groups_list = [tool_group.identifier for tool_group in tool_groups] mcp_tools_list = [tool for tool in tool_groups_list if tool.startswith("mcp::")] builtin_tools_list = [tool for tool in tool_groups_list if not tool.startswith("mcp::")] - selected_vector_dbs = [] + selected_vector_stores = [] def reset_agent(): st.session_state.clear() @@ -55,13 +55,13 @@ def tool_chat_page(): ) if "builtin::rag" in toolgroup_selection: - vector_dbs = llama_stack_api.client.vector_dbs.list() or [] - if not vector_dbs: + vector_stores = llama_stack_api.client.vector_stores.list() or [] + if not vector_stores: st.info("No vector databases available for selection.") - vector_dbs = [vector_db.identifier for vector_db in vector_dbs] - selected_vector_dbs = st.multiselect( + vector_stores = [vector_store.identifier for vector_store in vector_stores] + selected_vector_stores = st.multiselect( label="Select Document Collections to use in RAG queries", - options=vector_dbs, + options=vector_stores, on_change=reset_agent, ) @@ -119,7 +119,7 @@ def tool_chat_page(): tool_dict = dict( name="builtin::rag", args={ - "vector_db_ids": list(selected_vector_dbs), + "vector_store_ids": list(selected_vector_stores), }, ) toolgroup_selection[i] = tool_dict diff --git a/llama_stack/distributions/ci-tests/build.yaml b/llama_stack/distributions/ci-tests/build.yaml index 191d0ae59..c01e415a9 100644 --- a/llama_stack/distributions/ci-tests/build.yaml +++ b/llama_stack/distributions/ci-tests/build.yaml @@ -25,6 +25,8 @@ distribution_spec: - provider_type: inline::milvus - provider_type: remote::chromadb - provider_type: remote::pgvector + - provider_type: remote::qdrant + - provider_type: remote::weaviate files: - provider_type: inline::localfs safety: diff --git a/llama_stack/distributions/ci-tests/run.yaml b/llama_stack/distributions/ci-tests/run.yaml index a6a6b7c0d..ecf9eed3b 100644 --- a/llama_stack/distributions/ci-tests/run.yaml +++ b/llama_stack/distributions/ci-tests/run.yaml @@ -93,30 +93,30 @@ providers: - provider_id: faiss provider_type: inline::faiss config: - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/faiss_store.db + persistence: + namespace: vector_io::faiss + backend: kv_default - provider_id: sqlite-vec provider_type: inline::sqlite-vec config: db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/sqlite_vec.db - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/sqlite_vec_registry.db + persistence: + namespace: vector_io::sqlite_vec + backend: kv_default - provider_id: ${env.MILVUS_URL:+milvus} provider_type: inline::milvus config: db_path: ${env.MILVUS_DB_PATH:=~/.llama/distributions/ci-tests}/milvus.db - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/milvus_registry.db + persistence: + namespace: vector_io::milvus + backend: kv_default - provider_id: ${env.CHROMADB_URL:+chromadb} provider_type: remote::chromadb config: url: ${env.CHROMADB_URL:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests/}/chroma_remote_registry.db + persistence: + namespace: vector_io::chroma_remote + backend: kv_default - provider_id: ${env.PGVECTOR_DB:+pgvector} provider_type: remote::pgvector config: @@ -125,17 +125,32 @@ providers: db: ${env.PGVECTOR_DB:=} user: ${env.PGVECTOR_USER:=} password: ${env.PGVECTOR_PASSWORD:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/pgvector_registry.db + persistence: + namespace: vector_io::pgvector + backend: kv_default + - provider_id: ${env.QDRANT_URL:+qdrant} + provider_type: remote::qdrant + config: + api_key: ${env.QDRANT_API_KEY:=} + persistence: + namespace: vector_io::qdrant_remote + backend: kv_default + - provider_id: ${env.WEAVIATE_CLUSTER_URL:+weaviate} + provider_type: remote::weaviate + config: + weaviate_api_key: null + weaviate_cluster_url: ${env.WEAVIATE_CLUSTER_URL:=localhost:8080} + persistence: + namespace: vector_io::weaviate + backend: kv_default files: - provider_id: meta-reference-files provider_type: inline::localfs config: storage_dir: ${env.FILES_STORAGE_DIR:=~/.llama/distributions/ci-tests/files} metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/files_metadata.db + table_name: files_metadata + backend: sql_default safety: - provider_id: llama-guard provider_type: inline::llama-guard @@ -147,12 +162,15 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 post_training: - provider_id: torchtune-cpu provider_type: inline::torchtune-cpu @@ -163,21 +181,21 @@ providers: provider_type: inline::meta-reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/meta_reference_eval.db + namespace: eval + backend: kv_default datasetio: - provider_id: huggingface provider_type: remote::huggingface config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/huggingface_datasetio.db + namespace: datasetio::huggingface + backend: kv_default - provider_id: localfs provider_type: inline::localfs config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default scoring: - provider_id: basic provider_type: inline::basic @@ -207,35 +225,52 @@ providers: provider_type: inline::reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/batches.db -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/conversations.db -models: [] -shields: -- shield_id: llama-guard - provider_id: ${env.SAFETY_MODEL:+llama-guard} - provider_shield_id: ${env.SAFETY_MODEL:=} -- shield_id: code-scanner - provider_id: ${env.CODE_SCANNER_MODEL:+code-scanner} - provider_shield_id: ${env.CODE_SCANNER_MODEL:=} -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::websearch - provider_id: tavily-search -- toolgroup_id: builtin::rag - provider_id: rag-runtime + namespace: batches + backend: kv_default +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/ci-tests}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: [] + shields: + - shield_id: llama-guard + provider_id: ${env.SAFETY_MODEL:+llama-guard} + provider_shield_id: ${env.SAFETY_MODEL:=} + - shield_id: code-scanner + provider_id: ${env.CODE_SCANNER_MODEL:+code-scanner} + provider_shield_id: ${env.CODE_SCANNER_MODEL:=} + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: tavily-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: enabled: true +vector_stores: + default_provider_id: faiss + default_embedding_model: + provider_id: sentence-transformers + model_id: nomic-ai/nomic-embed-text-v1.5 diff --git a/llama_stack/distributions/dell/doc_template.md b/llama_stack/distributions/dell/doc_template.md index 852e78d0e..4e28673e8 100644 --- a/llama_stack/distributions/dell/doc_template.md +++ b/llama_stack/distributions/dell/doc_template.md @@ -157,7 +157,7 @@ docker run \ Make sure you have done `pip install llama-stack` and have the Llama Stack CLI available. ```bash -llama stack build --distro {{ name }} --image-type conda +llama stack list-deps {{ name }} | xargs -L1 pip install INFERENCE_MODEL=$INFERENCE_MODEL \ DEH_URL=$DEH_URL \ CHROMA_URL=$CHROMA_URL \ diff --git a/llama_stack/distributions/dell/run-with-safety.yaml b/llama_stack/distributions/dell/run-with-safety.yaml index 5da3cf511..2563f2f4b 100644 --- a/llama_stack/distributions/dell/run-with-safety.yaml +++ b/llama_stack/distributions/dell/run-with-safety.yaml @@ -26,9 +26,9 @@ providers: provider_type: remote::chromadb config: url: ${env.CHROMADB_URL:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell/}/chroma_remote_registry.db + persistence: + namespace: vector_io::chroma_remote + backend: kv_default safety: - provider_id: llama-guard provider_type: inline::llama-guard @@ -38,32 +38,35 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 eval: - provider_id: meta-reference provider_type: inline::meta-reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/meta_reference_eval.db + namespace: eval + backend: kv_default datasetio: - provider_id: huggingface provider_type: remote::huggingface config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/huggingface_datasetio.db + namespace: datasetio::huggingface + backend: kv_default - provider_id: localfs provider_type: inline::localfs config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default scoring: - provider_id: basic provider_type: inline::basic @@ -86,40 +89,52 @@ providers: max_results: 3 - provider_id: rag-runtime provider_type: inline::rag-runtime -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/conversations.db -models: -- metadata: {} - model_id: ${env.INFERENCE_MODEL} - provider_id: tgi0 - model_type: llm -- metadata: {} - model_id: ${env.SAFETY_MODEL} - provider_id: tgi1 - model_type: llm -- metadata: - embedding_dimension: 768 - model_id: nomic-embed-text-v1.5 - provider_id: sentence-transformers - model_type: embedding -shields: -- shield_id: ${env.SAFETY_MODEL} -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::websearch - provider_id: brave-search -- toolgroup_id: builtin::rag - provider_id: rag-runtime +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: + - metadata: {} + model_id: ${env.INFERENCE_MODEL} + provider_id: tgi0 + model_type: llm + - metadata: {} + model_id: ${env.SAFETY_MODEL} + provider_id: tgi1 + model_type: llm + - metadata: + embedding_dimension: 768 + model_id: nomic-embed-text-v1.5 + provider_id: sentence-transformers + model_type: embedding + shields: + - shield_id: ${env.SAFETY_MODEL} + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: brave-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: diff --git a/llama_stack/distributions/dell/run.yaml b/llama_stack/distributions/dell/run.yaml index ac0fdc0fa..7bada394f 100644 --- a/llama_stack/distributions/dell/run.yaml +++ b/llama_stack/distributions/dell/run.yaml @@ -22,9 +22,9 @@ providers: provider_type: remote::chromadb config: url: ${env.CHROMADB_URL:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell/}/chroma_remote_registry.db + persistence: + namespace: vector_io::chroma_remote + backend: kv_default safety: - provider_id: llama-guard provider_type: inline::llama-guard @@ -34,32 +34,35 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 eval: - provider_id: meta-reference provider_type: inline::meta-reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/meta_reference_eval.db + namespace: eval + backend: kv_default datasetio: - provider_id: huggingface provider_type: remote::huggingface config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/huggingface_datasetio.db + namespace: datasetio::huggingface + backend: kv_default - provider_id: localfs provider_type: inline::localfs config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default scoring: - provider_id: basic provider_type: inline::basic @@ -82,35 +85,47 @@ providers: max_results: 3 - provider_id: rag-runtime provider_type: inline::rag-runtime -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/conversations.db -models: -- metadata: {} - model_id: ${env.INFERENCE_MODEL} - provider_id: tgi0 - model_type: llm -- metadata: - embedding_dimension: 768 - model_id: nomic-embed-text-v1.5 - provider_id: sentence-transformers - model_type: embedding -shields: [] -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::websearch - provider_id: brave-search -- toolgroup_id: builtin::rag - provider_id: rag-runtime +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/dell}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: + - metadata: {} + model_id: ${env.INFERENCE_MODEL} + provider_id: tgi0 + model_type: llm + - metadata: + embedding_dimension: 768 + model_id: nomic-embed-text-v1.5 + provider_id: sentence-transformers + model_type: embedding + shields: [] + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: brave-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: diff --git a/llama_stack/distributions/meta-reference-gpu/run-with-safety.yaml b/llama_stack/distributions/meta-reference-gpu/run-with-safety.yaml index 874c5050f..01b5db4f9 100644 --- a/llama_stack/distributions/meta-reference-gpu/run-with-safety.yaml +++ b/llama_stack/distributions/meta-reference-gpu/run-with-safety.yaml @@ -37,9 +37,9 @@ providers: - provider_id: faiss provider_type: inline::faiss config: - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/faiss_store.db + persistence: + namespace: vector_io::faiss + backend: kv_default safety: - provider_id: llama-guard provider_type: inline::llama-guard @@ -49,32 +49,35 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 eval: - provider_id: meta-reference provider_type: inline::meta-reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/meta_reference_eval.db + namespace: eval + backend: kv_default datasetio: - provider_id: huggingface provider_type: remote::huggingface config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/huggingface_datasetio.db + namespace: datasetio::huggingface + backend: kv_default - provider_id: localfs provider_type: inline::localfs config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default scoring: - provider_id: basic provider_type: inline::basic @@ -99,40 +102,52 @@ providers: provider_type: inline::rag-runtime - provider_id: model-context-protocol provider_type: remote::model-context-protocol -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/conversations.db -models: -- metadata: {} - model_id: ${env.INFERENCE_MODEL} - provider_id: meta-reference-inference - model_type: llm -- metadata: {} - model_id: ${env.SAFETY_MODEL} - provider_id: meta-reference-safety - model_type: llm -- metadata: - embedding_dimension: 768 - model_id: nomic-embed-text-v1.5 - provider_id: sentence-transformers - model_type: embedding -shields: -- shield_id: ${env.SAFETY_MODEL} -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::websearch - provider_id: tavily-search -- toolgroup_id: builtin::rag - provider_id: rag-runtime +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: + - metadata: {} + model_id: ${env.INFERENCE_MODEL} + provider_id: meta-reference-inference + model_type: llm + - metadata: {} + model_id: ${env.SAFETY_MODEL} + provider_id: meta-reference-safety + model_type: llm + - metadata: + embedding_dimension: 768 + model_id: nomic-embed-text-v1.5 + provider_id: sentence-transformers + model_type: embedding + shields: + - shield_id: ${env.SAFETY_MODEL} + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: tavily-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: diff --git a/llama_stack/distributions/meta-reference-gpu/run.yaml b/llama_stack/distributions/meta-reference-gpu/run.yaml index 50553d2c7..87c33dde0 100644 --- a/llama_stack/distributions/meta-reference-gpu/run.yaml +++ b/llama_stack/distributions/meta-reference-gpu/run.yaml @@ -27,9 +27,9 @@ providers: - provider_id: faiss provider_type: inline::faiss config: - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/faiss_store.db + persistence: + namespace: vector_io::faiss + backend: kv_default safety: - provider_id: llama-guard provider_type: inline::llama-guard @@ -39,32 +39,35 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 eval: - provider_id: meta-reference provider_type: inline::meta-reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/meta_reference_eval.db + namespace: eval + backend: kv_default datasetio: - provider_id: huggingface provider_type: remote::huggingface config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/huggingface_datasetio.db + namespace: datasetio::huggingface + backend: kv_default - provider_id: localfs provider_type: inline::localfs config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default scoring: - provider_id: basic provider_type: inline::basic @@ -89,35 +92,47 @@ providers: provider_type: inline::rag-runtime - provider_id: model-context-protocol provider_type: remote::model-context-protocol -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/conversations.db -models: -- metadata: {} - model_id: ${env.INFERENCE_MODEL} - provider_id: meta-reference-inference - model_type: llm -- metadata: - embedding_dimension: 768 - model_id: nomic-embed-text-v1.5 - provider_id: sentence-transformers - model_type: embedding -shields: [] -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::websearch - provider_id: tavily-search -- toolgroup_id: builtin::rag - provider_id: rag-runtime +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/meta-reference-gpu}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: + - metadata: {} + model_id: ${env.INFERENCE_MODEL} + provider_id: meta-reference-inference + model_type: llm + - metadata: + embedding_dimension: 768 + model_id: nomic-embed-text-v1.5 + provider_id: sentence-transformers + model_type: embedding + shields: [] + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: tavily-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: diff --git a/llama_stack/distributions/nvidia/run-with-safety.yaml b/llama_stack/distributions/nvidia/run-with-safety.yaml index e0482f67d..c23d0f9cb 100644 --- a/llama_stack/distributions/nvidia/run-with-safety.yaml +++ b/llama_stack/distributions/nvidia/run-with-safety.yaml @@ -28,9 +28,9 @@ providers: - provider_id: faiss provider_type: inline::faiss config: - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/faiss_store.db + persistence: + namespace: vector_io::faiss + backend: kv_default safety: - provider_id: nvidia provider_type: remote::nvidia @@ -41,12 +41,15 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 eval: - provider_id: nvidia provider_type: remote::nvidia @@ -65,8 +68,8 @@ providers: provider_type: inline::localfs config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default - provider_id: nvidia provider_type: remote::nvidia config: @@ -86,36 +89,48 @@ providers: config: storage_dir: ${env.FILES_STORAGE_DIR:=~/.llama/distributions/nvidia/files} metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/files_metadata.db -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/conversations.db -models: -- metadata: {} - model_id: ${env.INFERENCE_MODEL} - provider_id: nvidia - model_type: llm -- metadata: {} - model_id: ${env.SAFETY_MODEL} - provider_id: nvidia - model_type: llm -shields: -- shield_id: ${env.SAFETY_MODEL} - provider_id: nvidia -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::rag - provider_id: rag-runtime + table_name: files_metadata + backend: sql_default +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: + - metadata: {} + model_id: ${env.INFERENCE_MODEL} + provider_id: nvidia + model_type: llm + - metadata: {} + model_id: ${env.SAFETY_MODEL} + provider_id: nvidia + model_type: llm + shields: + - shield_id: ${env.SAFETY_MODEL} + provider_id: nvidia + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: diff --git a/llama_stack/distributions/nvidia/run.yaml b/llama_stack/distributions/nvidia/run.yaml index 950782eed..81e744d53 100644 --- a/llama_stack/distributions/nvidia/run.yaml +++ b/llama_stack/distributions/nvidia/run.yaml @@ -23,9 +23,9 @@ providers: - provider_id: faiss provider_type: inline::faiss config: - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/faiss_store.db + persistence: + namespace: vector_io::faiss + backend: kv_default safety: - provider_id: nvidia provider_type: remote::nvidia @@ -36,12 +36,15 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 eval: - provider_id: nvidia provider_type: remote::nvidia @@ -75,26 +78,38 @@ providers: config: storage_dir: ${env.FILES_STORAGE_DIR:=~/.llama/distributions/nvidia/files} metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/files_metadata.db -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/conversations.db -models: [] -shields: [] -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::rag - provider_id: rag-runtime + table_name: files_metadata + backend: sql_default +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/nvidia}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: [] + shields: [] + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: diff --git a/llama_stack/distributions/open-benchmark/run.yaml b/llama_stack/distributions/open-benchmark/run.yaml index a738887b4..4fd0e199b 100644 --- a/llama_stack/distributions/open-benchmark/run.yaml +++ b/llama_stack/distributions/open-benchmark/run.yaml @@ -39,16 +39,16 @@ providers: provider_type: inline::sqlite-vec config: db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/sqlite_vec.db - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/sqlite_vec_registry.db + persistence: + namespace: vector_io::sqlite_vec + backend: kv_default - provider_id: ${env.ENABLE_CHROMADB:+chromadb} provider_type: remote::chromadb config: url: ${env.CHROMADB_URL:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/chroma_remote_registry.db + persistence: + namespace: vector_io::chroma_remote + backend: kv_default - provider_id: ${env.ENABLE_PGVECTOR:+pgvector} provider_type: remote::pgvector config: @@ -57,9 +57,9 @@ providers: db: ${env.PGVECTOR_DB:=} user: ${env.PGVECTOR_USER:=} password: ${env.PGVECTOR_PASSWORD:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/pgvector_registry.db + persistence: + namespace: vector_io::pgvector + backend: kv_default safety: - provider_id: llama-guard provider_type: inline::llama-guard @@ -69,32 +69,35 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 eval: - provider_id: meta-reference provider_type: inline::meta-reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/meta_reference_eval.db + namespace: eval + backend: kv_default datasetio: - provider_id: huggingface provider_type: remote::huggingface config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/huggingface_datasetio.db + namespace: datasetio::huggingface + backend: kv_default - provider_id: localfs provider_type: inline::localfs config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default scoring: - provider_id: basic provider_type: inline::basic @@ -119,118 +122,130 @@ providers: provider_type: inline::rag-runtime - provider_id: model-context-protocol provider_type: remote::model-context-protocol -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/conversations.db -models: -- metadata: {} - model_id: gpt-4o - provider_id: openai - provider_model_id: gpt-4o - model_type: llm -- metadata: {} - model_id: claude-3-5-sonnet-latest - provider_id: anthropic - provider_model_id: claude-3-5-sonnet-latest - model_type: llm -- metadata: {} - model_id: gemini/gemini-1.5-flash - provider_id: gemini - provider_model_id: gemini/gemini-1.5-flash - model_type: llm -- metadata: {} - model_id: meta-llama/Llama-3.3-70B-Instruct - provider_id: groq - provider_model_id: groq/llama-3.3-70b-versatile - model_type: llm -- metadata: {} - model_id: meta-llama/Llama-3.1-405B-Instruct - provider_id: together - provider_model_id: meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo - model_type: llm -shields: -- shield_id: meta-llama/Llama-Guard-3-8B -vector_dbs: [] -datasets: -- purpose: eval/messages-answer - source: - type: uri - uri: huggingface://datasets/llamastack/simpleqa?split=train - metadata: {} - dataset_id: simpleqa -- purpose: eval/messages-answer - source: - type: uri - uri: huggingface://datasets/llamastack/mmlu_cot?split=test&name=all - metadata: {} - dataset_id: mmlu_cot -- purpose: eval/messages-answer - source: - type: uri - uri: huggingface://datasets/llamastack/gpqa_0shot_cot?split=test&name=gpqa_main - metadata: {} - dataset_id: gpqa_cot -- purpose: eval/messages-answer - source: - type: uri - uri: huggingface://datasets/llamastack/math_500?split=test - metadata: {} - dataset_id: math_500 -- purpose: eval/messages-answer - source: - type: uri - uri: huggingface://datasets/llamastack/IfEval?split=train - metadata: {} - dataset_id: ifeval -- purpose: eval/messages-answer - source: - type: uri - uri: huggingface://datasets/llamastack/docvqa?split=val - metadata: {} - dataset_id: docvqa -scoring_fns: [] -benchmarks: -- dataset_id: simpleqa - scoring_functions: - - llm-as-judge::405b-simpleqa - metadata: {} - benchmark_id: meta-reference-simpleqa -- dataset_id: mmlu_cot - scoring_functions: - - basic::regex_parser_multiple_choice_answer - metadata: {} - benchmark_id: meta-reference-mmlu-cot -- dataset_id: gpqa_cot - scoring_functions: - - basic::regex_parser_multiple_choice_answer - metadata: {} - benchmark_id: meta-reference-gpqa-cot -- dataset_id: math_500 - scoring_functions: - - basic::regex_parser_math_response - metadata: {} - benchmark_id: meta-reference-math-500 -- dataset_id: ifeval - scoring_functions: - - basic::ifeval - metadata: {} - benchmark_id: meta-reference-ifeval -- dataset_id: docvqa - scoring_functions: - - basic::docvqa - metadata: {} - benchmark_id: meta-reference-docvqa -tool_groups: -- toolgroup_id: builtin::websearch - provider_id: tavily-search -- toolgroup_id: builtin::rag - provider_id: rag-runtime +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/open-benchmark}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: + - metadata: {} + model_id: gpt-4o + provider_id: openai + provider_model_id: gpt-4o + model_type: llm + - metadata: {} + model_id: claude-3-5-sonnet-latest + provider_id: anthropic + provider_model_id: claude-3-5-sonnet-latest + model_type: llm + - metadata: {} + model_id: gemini/gemini-1.5-flash + provider_id: gemini + provider_model_id: gemini/gemini-1.5-flash + model_type: llm + - metadata: {} + model_id: meta-llama/Llama-3.3-70B-Instruct + provider_id: groq + provider_model_id: groq/llama-3.3-70b-versatile + model_type: llm + - metadata: {} + model_id: meta-llama/Llama-3.1-405B-Instruct + provider_id: together + provider_model_id: meta-llama/Meta-Llama-3.1-405B-Instruct-Turbo + model_type: llm + shields: + - shield_id: meta-llama/Llama-Guard-3-8B + vector_dbs: [] + datasets: + - purpose: eval/messages-answer + source: + type: uri + uri: huggingface://datasets/llamastack/simpleqa?split=train + metadata: {} + dataset_id: simpleqa + - purpose: eval/messages-answer + source: + type: uri + uri: huggingface://datasets/llamastack/mmlu_cot?split=test&name=all + metadata: {} + dataset_id: mmlu_cot + - purpose: eval/messages-answer + source: + type: uri + uri: huggingface://datasets/llamastack/gpqa_0shot_cot?split=test&name=gpqa_main + metadata: {} + dataset_id: gpqa_cot + - purpose: eval/messages-answer + source: + type: uri + uri: huggingface://datasets/llamastack/math_500?split=test + metadata: {} + dataset_id: math_500 + - purpose: eval/messages-answer + source: + type: uri + uri: huggingface://datasets/llamastack/IfEval?split=train + metadata: {} + dataset_id: ifeval + - purpose: eval/messages-answer + source: + type: uri + uri: huggingface://datasets/llamastack/docvqa?split=val + metadata: {} + dataset_id: docvqa + scoring_fns: [] + benchmarks: + - dataset_id: simpleqa + scoring_functions: + - llm-as-judge::405b-simpleqa + metadata: {} + benchmark_id: meta-reference-simpleqa + - dataset_id: mmlu_cot + scoring_functions: + - basic::regex_parser_multiple_choice_answer + metadata: {} + benchmark_id: meta-reference-mmlu-cot + - dataset_id: gpqa_cot + scoring_functions: + - basic::regex_parser_multiple_choice_answer + metadata: {} + benchmark_id: meta-reference-gpqa-cot + - dataset_id: math_500 + scoring_functions: + - basic::regex_parser_math_response + metadata: {} + benchmark_id: meta-reference-math-500 + - dataset_id: ifeval + scoring_functions: + - basic::ifeval + metadata: {} + benchmark_id: meta-reference-ifeval + - dataset_id: docvqa + scoring_functions: + - basic::docvqa + metadata: {} + benchmark_id: meta-reference-docvqa + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: tavily-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: diff --git a/llama_stack/distributions/postgres-demo/postgres_demo.py b/llama_stack/distributions/postgres-demo/postgres_demo.py index 1f3e88b3b..876370ef3 100644 --- a/llama_stack/distributions/postgres-demo/postgres_demo.py +++ b/llama_stack/distributions/postgres-demo/postgres_demo.py @@ -91,7 +91,6 @@ def get_distribution_template() -> DistributionTemplate: "embedding_dimension": 768, }, ) - postgres_config = PostgresSqlStoreConfig.sample_run_config() return DistributionTemplate( name=name, distro_type="self_hosted", @@ -105,22 +104,16 @@ def get_distribution_template() -> DistributionTemplate: provider_overrides={ "inference": inference_providers + [embedding_provider], "vector_io": vector_io_providers, - "agents": [ - Provider( - provider_id="meta-reference", - provider_type="inline::meta-reference", - config=dict( - persistence_store=postgres_config, - responses_store=postgres_config, - ), - ) - ], }, default_models=default_models + [embedding_model], default_tool_groups=default_tool_groups, default_shields=[ShieldInput(shield_id="meta-llama/Llama-Guard-3-8B")], - metadata_store=PostgresKVStoreConfig.sample_run_config(), - inference_store=postgres_config, + storage_backends={ + "kv_default": PostgresKVStoreConfig.sample_run_config( + table_name="llamastack_kvstore", + ), + "sql_default": PostgresSqlStoreConfig.sample_run_config(), + }, ), }, run_config_env_vars={ diff --git a/llama_stack/distributions/postgres-demo/run.yaml b/llama_stack/distributions/postgres-demo/run.yaml index 62faf3f62..0d7ecff48 100644 --- a/llama_stack/distributions/postgres-demo/run.yaml +++ b/llama_stack/distributions/postgres-demo/run.yaml @@ -22,9 +22,9 @@ providers: provider_type: remote::chromadb config: url: ${env.CHROMADB_URL:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/postgres-demo}/chroma_remote_registry.db + persistence: + namespace: vector_io::chroma_remote + backend: kv_default safety: - provider_id: llama-guard provider_type: inline::llama-guard @@ -34,20 +34,15 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: postgres - host: ${env.POSTGRES_HOST:=localhost} - port: ${env.POSTGRES_PORT:=5432} - db: ${env.POSTGRES_DB:=llamastack} - user: ${env.POSTGRES_USER:=llamastack} - password: ${env.POSTGRES_PASSWORD:=llamastack} - responses_store: - type: postgres - host: ${env.POSTGRES_HOST:=localhost} - port: ${env.POSTGRES_PORT:=5432} - db: ${env.POSTGRES_DB:=llamastack} - user: ${env.POSTGRES_USER:=llamastack} - password: ${env.POSTGRES_PASSWORD:=llamastack} + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 tool_runtime: - provider_id: brave-search provider_type: remote::brave-search @@ -63,45 +58,57 @@ providers: provider_type: inline::rag-runtime - provider_id: model-context-protocol provider_type: remote::model-context-protocol -metadata_store: - type: postgres - host: ${env.POSTGRES_HOST:=localhost} - port: ${env.POSTGRES_PORT:=5432} - db: ${env.POSTGRES_DB:=llamastack} - user: ${env.POSTGRES_USER:=llamastack} - password: ${env.POSTGRES_PASSWORD:=llamastack} - table_name: ${env.POSTGRES_TABLE_NAME:=llamastack_kvstore} -inference_store: - type: postgres - host: ${env.POSTGRES_HOST:=localhost} - port: ${env.POSTGRES_PORT:=5432} - db: ${env.POSTGRES_DB:=llamastack} - user: ${env.POSTGRES_USER:=llamastack} - password: ${env.POSTGRES_PASSWORD:=llamastack} -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/postgres-demo}/conversations.db -models: -- metadata: {} - model_id: ${env.INFERENCE_MODEL} - provider_id: vllm-inference - model_type: llm -- metadata: - embedding_dimension: 768 - model_id: nomic-embed-text-v1.5 - provider_id: sentence-transformers - model_type: embedding -shields: -- shield_id: meta-llama/Llama-Guard-3-8B -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::websearch - provider_id: tavily-search -- toolgroup_id: builtin::rag - provider_id: rag-runtime +storage: + backends: + kv_default: + type: kv_postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + table_name: ${env.POSTGRES_TABLE_NAME:=llamastack_kvstore} + sql_default: + type: sql_postgres + host: ${env.POSTGRES_HOST:=localhost} + port: ${env.POSTGRES_PORT:=5432} + db: ${env.POSTGRES_DB:=llamastack} + user: ${env.POSTGRES_USER:=llamastack} + password: ${env.POSTGRES_PASSWORD:=llamastack} + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: + - metadata: {} + model_id: ${env.INFERENCE_MODEL} + provider_id: vllm-inference + model_type: llm + - metadata: + embedding_dimension: 768 + model_id: nomic-embed-text-v1.5 + provider_id: sentence-transformers + model_type: embedding + shields: + - shield_id: meta-llama/Llama-Guard-3-8B + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: tavily-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: diff --git a/llama_stack/distributions/starter-gpu/build.yaml b/llama_stack/distributions/starter-gpu/build.yaml index 943c6134d..b2e2a0c85 100644 --- a/llama_stack/distributions/starter-gpu/build.yaml +++ b/llama_stack/distributions/starter-gpu/build.yaml @@ -26,6 +26,8 @@ distribution_spec: - provider_type: inline::milvus - provider_type: remote::chromadb - provider_type: remote::pgvector + - provider_type: remote::qdrant + - provider_type: remote::weaviate files: - provider_type: inline::localfs safety: diff --git a/llama_stack/distributions/starter-gpu/run.yaml b/llama_stack/distributions/starter-gpu/run.yaml index 370d4b516..92483c78e 100644 --- a/llama_stack/distributions/starter-gpu/run.yaml +++ b/llama_stack/distributions/starter-gpu/run.yaml @@ -93,30 +93,30 @@ providers: - provider_id: faiss provider_type: inline::faiss config: - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/faiss_store.db + persistence: + namespace: vector_io::faiss + backend: kv_default - provider_id: sqlite-vec provider_type: inline::sqlite-vec config: db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/sqlite_vec.db - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/sqlite_vec_registry.db + persistence: + namespace: vector_io::sqlite_vec + backend: kv_default - provider_id: ${env.MILVUS_URL:+milvus} provider_type: inline::milvus config: db_path: ${env.MILVUS_DB_PATH:=~/.llama/distributions/starter-gpu}/milvus.db - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/milvus_registry.db + persistence: + namespace: vector_io::milvus + backend: kv_default - provider_id: ${env.CHROMADB_URL:+chromadb} provider_type: remote::chromadb config: url: ${env.CHROMADB_URL:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu/}/chroma_remote_registry.db + persistence: + namespace: vector_io::chroma_remote + backend: kv_default - provider_id: ${env.PGVECTOR_DB:+pgvector} provider_type: remote::pgvector config: @@ -125,17 +125,32 @@ providers: db: ${env.PGVECTOR_DB:=} user: ${env.PGVECTOR_USER:=} password: ${env.PGVECTOR_PASSWORD:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/pgvector_registry.db + persistence: + namespace: vector_io::pgvector + backend: kv_default + - provider_id: ${env.QDRANT_URL:+qdrant} + provider_type: remote::qdrant + config: + api_key: ${env.QDRANT_API_KEY:=} + persistence: + namespace: vector_io::qdrant_remote + backend: kv_default + - provider_id: ${env.WEAVIATE_CLUSTER_URL:+weaviate} + provider_type: remote::weaviate + config: + weaviate_api_key: null + weaviate_cluster_url: ${env.WEAVIATE_CLUSTER_URL:=localhost:8080} + persistence: + namespace: vector_io::weaviate + backend: kv_default files: - provider_id: meta-reference-files provider_type: inline::localfs config: storage_dir: ${env.FILES_STORAGE_DIR:=~/.llama/distributions/starter-gpu/files} metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/files_metadata.db + table_name: files_metadata + backend: sql_default safety: - provider_id: llama-guard provider_type: inline::llama-guard @@ -147,12 +162,15 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 post_training: - provider_id: huggingface-gpu provider_type: inline::huggingface-gpu @@ -166,21 +184,21 @@ providers: provider_type: inline::meta-reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/meta_reference_eval.db + namespace: eval + backend: kv_default datasetio: - provider_id: huggingface provider_type: remote::huggingface config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/huggingface_datasetio.db + namespace: datasetio::huggingface + backend: kv_default - provider_id: localfs provider_type: inline::localfs config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default scoring: - provider_id: basic provider_type: inline::basic @@ -210,35 +228,52 @@ providers: provider_type: inline::reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/batches.db -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/conversations.db -models: [] -shields: -- shield_id: llama-guard - provider_id: ${env.SAFETY_MODEL:+llama-guard} - provider_shield_id: ${env.SAFETY_MODEL:=} -- shield_id: code-scanner - provider_id: ${env.CODE_SCANNER_MODEL:+code-scanner} - provider_shield_id: ${env.CODE_SCANNER_MODEL:=} -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::websearch - provider_id: tavily-search -- toolgroup_id: builtin::rag - provider_id: rag-runtime + namespace: batches + backend: kv_default +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter-gpu}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: [] + shields: + - shield_id: llama-guard + provider_id: ${env.SAFETY_MODEL:+llama-guard} + provider_shield_id: ${env.SAFETY_MODEL:=} + - shield_id: code-scanner + provider_id: ${env.CODE_SCANNER_MODEL:+code-scanner} + provider_shield_id: ${env.CODE_SCANNER_MODEL:=} + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: tavily-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: enabled: true +vector_stores: + default_provider_id: faiss + default_embedding_model: + provider_id: sentence-transformers + model_id: nomic-ai/nomic-embed-text-v1.5 diff --git a/llama_stack/distributions/starter/build.yaml b/llama_stack/distributions/starter/build.yaml index c2719d50d..baa80ef3e 100644 --- a/llama_stack/distributions/starter/build.yaml +++ b/llama_stack/distributions/starter/build.yaml @@ -26,6 +26,8 @@ distribution_spec: - provider_type: inline::milvus - provider_type: remote::chromadb - provider_type: remote::pgvector + - provider_type: remote::qdrant + - provider_type: remote::weaviate files: - provider_type: inline::localfs safety: diff --git a/llama_stack/distributions/starter/run.yaml b/llama_stack/distributions/starter/run.yaml index 2f4e7f350..3b9d8f890 100644 --- a/llama_stack/distributions/starter/run.yaml +++ b/llama_stack/distributions/starter/run.yaml @@ -93,30 +93,30 @@ providers: - provider_id: faiss provider_type: inline::faiss config: - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/faiss_store.db + persistence: + namespace: vector_io::faiss + backend: kv_default - provider_id: sqlite-vec provider_type: inline::sqlite-vec config: db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/sqlite_vec.db - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/sqlite_vec_registry.db + persistence: + namespace: vector_io::sqlite_vec + backend: kv_default - provider_id: ${env.MILVUS_URL:+milvus} provider_type: inline::milvus config: db_path: ${env.MILVUS_DB_PATH:=~/.llama/distributions/starter}/milvus.db - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/milvus_registry.db + persistence: + namespace: vector_io::milvus + backend: kv_default - provider_id: ${env.CHROMADB_URL:+chromadb} provider_type: remote::chromadb config: url: ${env.CHROMADB_URL:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter/}/chroma_remote_registry.db + persistence: + namespace: vector_io::chroma_remote + backend: kv_default - provider_id: ${env.PGVECTOR_DB:+pgvector} provider_type: remote::pgvector config: @@ -125,17 +125,32 @@ providers: db: ${env.PGVECTOR_DB:=} user: ${env.PGVECTOR_USER:=} password: ${env.PGVECTOR_PASSWORD:=} - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/pgvector_registry.db + persistence: + namespace: vector_io::pgvector + backend: kv_default + - provider_id: ${env.QDRANT_URL:+qdrant} + provider_type: remote::qdrant + config: + api_key: ${env.QDRANT_API_KEY:=} + persistence: + namespace: vector_io::qdrant_remote + backend: kv_default + - provider_id: ${env.WEAVIATE_CLUSTER_URL:+weaviate} + provider_type: remote::weaviate + config: + weaviate_api_key: null + weaviate_cluster_url: ${env.WEAVIATE_CLUSTER_URL:=localhost:8080} + persistence: + namespace: vector_io::weaviate + backend: kv_default files: - provider_id: meta-reference-files provider_type: inline::localfs config: storage_dir: ${env.FILES_STORAGE_DIR:=~/.llama/distributions/starter/files} metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/files_metadata.db + table_name: files_metadata + backend: sql_default safety: - provider_id: llama-guard provider_type: inline::llama-guard @@ -147,12 +162,15 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 post_training: - provider_id: torchtune-cpu provider_type: inline::torchtune-cpu @@ -163,21 +181,21 @@ providers: provider_type: inline::meta-reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/meta_reference_eval.db + namespace: eval + backend: kv_default datasetio: - provider_id: huggingface provider_type: remote::huggingface config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/huggingface_datasetio.db + namespace: datasetio::huggingface + backend: kv_default - provider_id: localfs provider_type: inline::localfs config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default scoring: - provider_id: basic provider_type: inline::basic @@ -207,35 +225,52 @@ providers: provider_type: inline::reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/batches.db -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/conversations.db -models: [] -shields: -- shield_id: llama-guard - provider_id: ${env.SAFETY_MODEL:+llama-guard} - provider_shield_id: ${env.SAFETY_MODEL:=} -- shield_id: code-scanner - provider_id: ${env.CODE_SCANNER_MODEL:+code-scanner} - provider_shield_id: ${env.CODE_SCANNER_MODEL:=} -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::websearch - provider_id: tavily-search -- toolgroup_id: builtin::rag - provider_id: rag-runtime + namespace: batches + backend: kv_default +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/starter}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: [] + shields: + - shield_id: llama-guard + provider_id: ${env.SAFETY_MODEL:+llama-guard} + provider_shield_id: ${env.SAFETY_MODEL:=} + - shield_id: code-scanner + provider_id: ${env.CODE_SCANNER_MODEL:+code-scanner} + provider_shield_id: ${env.CODE_SCANNER_MODEL:=} + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: tavily-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: enabled: true +vector_stores: + default_provider_id: faiss + default_embedding_model: + provider_id: sentence-transformers + model_id: nomic-ai/nomic-embed-text-v1.5 diff --git a/llama_stack/distributions/starter/starter.py b/llama_stack/distributions/starter/starter.py index f87ebcc5f..c8c7101a6 100644 --- a/llama_stack/distributions/starter/starter.py +++ b/llama_stack/distributions/starter/starter.py @@ -11,8 +11,10 @@ from llama_stack.core.datatypes import ( BuildProvider, Provider, ProviderSpec, + QualifiedModel, ShieldInput, ToolGroupInput, + VectorStoresConfig, ) from llama_stack.core.utils.dynamic import instantiate_class_type from llama_stack.distributions.template import DistributionTemplate, RunConfigSettings @@ -31,6 +33,8 @@ from llama_stack.providers.remote.vector_io.chroma.config import ChromaVectorIOC from llama_stack.providers.remote.vector_io.pgvector.config import ( PGVectorVectorIOConfig, ) +from llama_stack.providers.remote.vector_io.qdrant.config import QdrantVectorIOConfig +from llama_stack.providers.remote.vector_io.weaviate.config import WeaviateVectorIOConfig from llama_stack.providers.utils.sqlstore.sqlstore import PostgresSqlStoreConfig @@ -113,6 +117,8 @@ def get_distribution_template(name: str = "starter") -> DistributionTemplate: BuildProvider(provider_type="inline::milvus"), BuildProvider(provider_type="remote::chromadb"), BuildProvider(provider_type="remote::pgvector"), + BuildProvider(provider_type="remote::qdrant"), + BuildProvider(provider_type="remote::weaviate"), ], "files": [BuildProvider(provider_type="inline::localfs")], "safety": [ @@ -221,12 +227,35 @@ def get_distribution_template(name: str = "starter") -> DistributionTemplate: password="${env.PGVECTOR_PASSWORD:=}", ), ), + Provider( + provider_id="${env.QDRANT_URL:+qdrant}", + provider_type="remote::qdrant", + config=QdrantVectorIOConfig.sample_run_config( + f"~/.llama/distributions/{name}", + url="${env.QDRANT_URL:=}", + ), + ), + Provider( + provider_id="${env.WEAVIATE_CLUSTER_URL:+weaviate}", + provider_type="remote::weaviate", + config=WeaviateVectorIOConfig.sample_run_config( + f"~/.llama/distributions/{name}", + cluster_url="${env.WEAVIATE_CLUSTER_URL:=}", + ), + ), ], "files": [files_provider], }, default_models=[], default_tool_groups=default_tool_groups, default_shields=default_shields, + vector_stores_config=VectorStoresConfig( + default_provider_id="faiss", + default_embedding_model=QualifiedModel( + provider_id="sentence-transformers", + model_id="nomic-ai/nomic-embed-text-v1.5", + ), + ), ), }, run_config_env_vars={ diff --git a/llama_stack/distributions/template.py b/llama_stack/distributions/template.py index 807829999..64f21e626 100644 --- a/llama_stack/distributions/template.py +++ b/llama_stack/distributions/template.py @@ -27,8 +27,15 @@ from llama_stack.core.datatypes import ( ShieldInput, TelemetryConfig, ToolGroupInput, + VectorStoresConfig, ) from llama_stack.core.distribution import get_provider_registry +from llama_stack.core.storage.datatypes import ( + InferenceStoreReference, + KVStoreReference, + SqlStoreReference, + StorageBackendType, +) from llama_stack.core.utils.dynamic import instantiate_class_type from llama_stack.core.utils.image_types import LlamaStackImageType from llama_stack.providers.utils.inference.model_registry import ProviderModelEntry @@ -180,10 +187,10 @@ class RunConfigSettings(BaseModel): default_tool_groups: list[ToolGroupInput] | None = None default_datasets: list[DatasetInput] | None = None default_benchmarks: list[BenchmarkInput] | None = None - metadata_store: dict | None = None - inference_store: dict | None = None - conversations_store: dict | None = None + vector_stores_config: VectorStoresConfig | None = None telemetry: TelemetryConfig = Field(default_factory=lambda: TelemetryConfig(enabled=True)) + storage_backends: dict[str, Any] | None = None + storage_stores: dict[str, Any] | None = None def run_config( self, @@ -226,41 +233,65 @@ class RunConfigSettings(BaseModel): # Get unique set of APIs from providers apis = sorted(providers.keys()) + storage_backends = self.storage_backends or { + "kv_default": SqliteKVStoreConfig.sample_run_config( + __distro_dir__=f"~/.llama/distributions/{name}", + db_name="kvstore.db", + ), + "sql_default": SqliteSqlStoreConfig.sample_run_config( + __distro_dir__=f"~/.llama/distributions/{name}", + db_name="sql_store.db", + ), + } + + storage_stores = self.storage_stores or { + "metadata": KVStoreReference( + backend="kv_default", + namespace="registry", + ).model_dump(exclude_none=True), + "inference": InferenceStoreReference( + backend="sql_default", + table_name="inference_store", + ).model_dump(exclude_none=True), + "conversations": SqlStoreReference( + backend="sql_default", + table_name="openai_conversations", + ).model_dump(exclude_none=True), + } + + storage_config = dict( + backends=storage_backends, + stores=storage_stores, + ) + # Return a dict that matches StackRunConfig structure - return { + config = { "version": LLAMA_STACK_RUN_CONFIG_VERSION, "image_name": name, "container_image": container_image, "apis": apis, "providers": provider_configs, - "metadata_store": self.metadata_store - or SqliteKVStoreConfig.sample_run_config( - __distro_dir__=f"~/.llama/distributions/{name}", - db_name="registry.db", - ), - "inference_store": self.inference_store - or SqliteSqlStoreConfig.sample_run_config( - __distro_dir__=f"~/.llama/distributions/{name}", - db_name="inference_store.db", - ), - "conversations_store": self.conversations_store - or SqliteSqlStoreConfig.sample_run_config( - __distro_dir__=f"~/.llama/distributions/{name}", - db_name="conversations.db", - ), - "models": [m.model_dump(exclude_none=True) for m in (self.default_models or [])], - "shields": [s.model_dump(exclude_none=True) for s in (self.default_shields or [])], - "vector_dbs": [], - "datasets": [d.model_dump(exclude_none=True) for d in (self.default_datasets or [])], - "scoring_fns": [], - "benchmarks": [b.model_dump(exclude_none=True) for b in (self.default_benchmarks or [])], - "tool_groups": [t.model_dump(exclude_none=True) for t in (self.default_tool_groups or [])], + "storage": storage_config, + "registered_resources": { + "models": [m.model_dump(exclude_none=True) for m in (self.default_models or [])], + "shields": [s.model_dump(exclude_none=True) for s in (self.default_shields or [])], + "vector_dbs": [], + "datasets": [d.model_dump(exclude_none=True) for d in (self.default_datasets or [])], + "scoring_fns": [], + "benchmarks": [b.model_dump(exclude_none=True) for b in (self.default_benchmarks or [])], + "tool_groups": [t.model_dump(exclude_none=True) for t in (self.default_tool_groups or [])], + }, "server": { "port": 8321, }, "telemetry": self.telemetry.model_dump(exclude_none=True) if self.telemetry else None, } + if self.vector_stores_config: + config["vector_stores"] = self.vector_stores_config.model_dump(exclude_none=True) + + return config + class DistributionTemplate(BaseModel): """ @@ -297,11 +328,15 @@ class DistributionTemplate(BaseModel): # We should have a better way to do this by formalizing the concept of "internal" APIs # and providers, with a way to specify dependencies for them. - if run_config_.get("inference_store"): - additional_pip_packages.extend(get_sql_pip_packages(run_config_["inference_store"])) - - if run_config_.get("metadata_store"): - additional_pip_packages.extend(get_kv_pip_packages(run_config_["metadata_store"])) + storage_cfg = run_config_.get("storage", {}) + for backend_cfg in storage_cfg.get("backends", {}).values(): + store_type = backend_cfg.get("type") + if not store_type: + continue + if str(store_type).startswith("kv_"): + additional_pip_packages.extend(get_kv_pip_packages(backend_cfg)) + elif str(store_type).startswith("sql_"): + additional_pip_packages.extend(get_sql_pip_packages(backend_cfg)) if self.additional_pip_packages: additional_pip_packages.extend(self.additional_pip_packages) @@ -387,11 +422,13 @@ class DistributionTemplate(BaseModel): def enum_representer(dumper, data): return dumper.represent_scalar("tag:yaml.org,2002:str", data.value) - # Register YAML representer for ModelType + # Register YAML representer for enums yaml.add_representer(ModelType, enum_representer) yaml.add_representer(DatasetPurpose, enum_representer) + yaml.add_representer(StorageBackendType, enum_representer) yaml.SafeDumper.add_representer(ModelType, enum_representer) yaml.SafeDumper.add_representer(DatasetPurpose, enum_representer) + yaml.SafeDumper.add_representer(StorageBackendType, enum_representer) for output_dir in [yaml_output_dir, doc_output_dir]: output_dir.mkdir(parents=True, exist_ok=True) diff --git a/llama_stack/distributions/watsonx/run.yaml b/llama_stack/distributions/watsonx/run.yaml index c3db4eeb8..ca3c8402d 100644 --- a/llama_stack/distributions/watsonx/run.yaml +++ b/llama_stack/distributions/watsonx/run.yaml @@ -22,9 +22,9 @@ providers: - provider_id: faiss provider_type: inline::faiss config: - kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/faiss_store.db + persistence: + namespace: vector_io::faiss + backend: kv_default safety: - provider_id: llama-guard provider_type: inline::llama-guard @@ -34,32 +34,35 @@ providers: - provider_id: meta-reference provider_type: inline::meta-reference config: - persistence_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/agents_store.db - responses_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/responses_store.db + persistence: + agent_state: + namespace: agents + backend: kv_default + responses: + table_name: responses + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 eval: - provider_id: meta-reference provider_type: inline::meta-reference config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/meta_reference_eval.db + namespace: eval + backend: kv_default datasetio: - provider_id: huggingface provider_type: remote::huggingface config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/huggingface_datasetio.db + namespace: datasetio::huggingface + backend: kv_default - provider_id: localfs provider_type: inline::localfs config: kvstore: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/localfs_datasetio.db + namespace: datasetio::localfs + backend: kv_default scoring: - provider_id: basic provider_type: inline::basic @@ -90,28 +93,40 @@ providers: config: storage_dir: ${env.FILES_STORAGE_DIR:=~/.llama/distributions/watsonx/files} metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/files_metadata.db -metadata_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/registry.db -inference_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/inference_store.db -conversations_store: - type: sqlite - db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/conversations.db -models: [] -shields: [] -vector_dbs: [] -datasets: [] -scoring_fns: [] -benchmarks: [] -tool_groups: -- toolgroup_id: builtin::websearch - provider_id: tavily-search -- toolgroup_id: builtin::rag - provider_id: rag-runtime + table_name: files_metadata + backend: sql_default +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/watsonx}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + max_write_queue_size: 10000 + num_writers: 4 + conversations: + table_name: openai_conversations + backend: sql_default +registered_resources: + models: [] + shields: [] + vector_dbs: [] + datasets: [] + scoring_fns: [] + benchmarks: [] + tool_groups: + - toolgroup_id: builtin::websearch + provider_id: tavily-search + - toolgroup_id: builtin::rag + provider_id: rag-runtime server: port: 8321 telemetry: diff --git a/llama_stack/log.py b/llama_stack/log.py index ff54b2f7c..dc39f6881 100644 --- a/llama_stack/log.py +++ b/llama_stack/log.py @@ -166,14 +166,26 @@ class CustomFileHandler(logging.FileHandler): super().emit(record) -def setup_logging(category_levels: dict[str, int], log_file: str | None) -> None: +def setup_logging(category_levels: dict[str, int] | None = None, log_file: str | None = None) -> None: """ Configure logging based on the provided category log levels and an optional log file. + If category_levels or log_file are not provided, they will be read from environment variables. Parameters: - category_levels (Dict[str, int]): A dictionary mapping categories to their log levels. - log_file (str): Path to a log file to additionally pipe the logs into + category_levels (Dict[str, int] | None): A dictionary mapping categories to their log levels. + If None, reads from LLAMA_STACK_LOGGING environment variable and uses defaults. + log_file (str | None): Path to a log file to additionally pipe the logs into. + If None, reads from LLAMA_STACK_LOG_FILE environment variable. """ + # Read from environment variables if not explicitly provided + if category_levels is None: + category_levels = dict.fromkeys(CATEGORIES, DEFAULT_LOG_LEVEL) + env_config = os.environ.get("LLAMA_STACK_LOGGING", "") + if env_config: + category_levels.update(parse_environment_config(env_config)) + + if log_file is None: + log_file = os.environ.get("LLAMA_STACK_LOG_FILE") log_format = "%(asctime)s %(name)s:%(lineno)d %(category)s: %(message)s" class CategoryFilter(logging.Filter): @@ -224,12 +236,30 @@ def setup_logging(category_levels: dict[str, int], log_file: str | None) -> None } }, "loggers": { - category: { - "handlers": list(handlers.keys()), # Apply all handlers - "level": category_levels.get(category, DEFAULT_LOG_LEVEL), - "propagate": False, # Disable propagation to root logger - } - for category in CATEGORIES + **{ + category: { + "handlers": list(handlers.keys()), # Apply all handlers + "level": category_levels.get(category, DEFAULT_LOG_LEVEL), + "propagate": False, # Disable propagation to root logger + } + for category in CATEGORIES + }, + # Explicitly configure uvicorn loggers to preserve their INFO level + "uvicorn": { + "handlers": list(handlers.keys()), + "level": logging.INFO, + "propagate": False, + }, + "uvicorn.error": { + "handlers": list(handlers.keys()), + "level": logging.INFO, + "propagate": False, + }, + "uvicorn.access": { + "handlers": list(handlers.keys()), + "level": logging.INFO, + "propagate": False, + }, }, "root": { "handlers": list(handlers.keys()), @@ -238,9 +268,13 @@ def setup_logging(category_levels: dict[str, int], log_file: str | None) -> None } dictConfig(logging_config) - # Ensure third-party libraries follow the root log level - for _, logger in logging.root.manager.loggerDict.items(): + # Ensure third-party libraries follow the root log level, but preserve + # already-configured loggers (e.g., uvicorn) and our own llama_stack loggers + for name, logger in logging.root.manager.loggerDict.items(): if isinstance(logger, logging.Logger): + # Skip infrastructure loggers (uvicorn, fastapi) and our own loggers + if name.startswith(("uvicorn", "fastapi", "llama_stack")): + continue logger.setLevel(root_level) @@ -278,12 +312,3 @@ def get_logger( log_level = _category_levels.get("root", DEFAULT_LOG_LEVEL) logger.setLevel(log_level) return logging.LoggerAdapter(logger, {"category": category}) - - -env_config = os.environ.get("LLAMA_STACK_LOGGING", "") -if env_config: - _category_levels.update(parse_environment_config(env_config)) - -log_file = os.environ.get("LLAMA_STACK_LOG_FILE") - -setup_logging(_category_levels, log_file) diff --git a/llama_stack/providers/datatypes.py b/llama_stack/providers/datatypes.py index c8ff9cecb..9be3edb8e 100644 --- a/llama_stack/providers/datatypes.py +++ b/llama_stack/providers/datatypes.py @@ -17,7 +17,7 @@ from llama_stack.apis.models import Model from llama_stack.apis.scoring_functions import ScoringFn from llama_stack.apis.shields import Shield from llama_stack.apis.tools import ToolGroup -from llama_stack.apis.vector_dbs import VectorDB +from llama_stack.apis.vector_stores import VectorStore from llama_stack.schema_utils import json_schema_type @@ -68,10 +68,10 @@ class ShieldsProtocolPrivate(Protocol): async def unregister_shield(self, identifier: str) -> None: ... -class VectorDBsProtocolPrivate(Protocol): - async def register_vector_db(self, vector_db: VectorDB) -> None: ... +class VectorStoresProtocolPrivate(Protocol): + async def register_vector_store(self, vector_store: VectorStore) -> None: ... - async def unregister_vector_db(self, vector_db_id: str) -> None: ... + async def unregister_vector_store(self, vector_store_id: str) -> None: ... class DatasetsProtocolPrivate(Protocol): diff --git a/llama_stack/providers/inline/agents/meta_reference/agents.py b/llama_stack/providers/inline/agents/meta_reference/agents.py index 810c063e6..c2f6ea640 100644 --- a/llama_stack/providers/inline/agents/meta_reference/agents.py +++ b/llama_stack/providers/inline/agents/meta_reference/agents.py @@ -83,8 +83,8 @@ class MetaReferenceAgentsImpl(Agents): self.policy = policy async def initialize(self) -> None: - self.persistence_store = await kvstore_impl(self.config.persistence_store) - self.responses_store = ResponsesStore(self.config.responses_store, self.policy) + self.persistence_store = await kvstore_impl(self.config.persistence.agent_state) + self.responses_store = ResponsesStore(self.config.persistence.responses, self.policy) await self.responses_store.initialize() self.openai_responses_impl = OpenAIResponsesImpl( inference_api=self.inference_api, diff --git a/llama_stack/providers/inline/agents/meta_reference/config.py b/llama_stack/providers/inline/agents/meta_reference/config.py index 1c392f29c..a800b426b 100644 --- a/llama_stack/providers/inline/agents/meta_reference/config.py +++ b/llama_stack/providers/inline/agents/meta_reference/config.py @@ -8,24 +8,30 @@ from typing import Any from pydantic import BaseModel -from llama_stack.providers.utils.kvstore import KVStoreConfig -from llama_stack.providers.utils.kvstore.config import SqliteKVStoreConfig -from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig, SqlStoreConfig +from llama_stack.core.storage.datatypes import KVStoreReference, ResponsesStoreReference + + +class AgentPersistenceConfig(BaseModel): + """Nested persistence configuration for agents.""" + + agent_state: KVStoreReference + responses: ResponsesStoreReference class MetaReferenceAgentsImplConfig(BaseModel): - persistence_store: KVStoreConfig - responses_store: SqlStoreConfig + persistence: AgentPersistenceConfig @classmethod def sample_run_config(cls, __distro_dir__: str) -> dict[str, Any]: return { - "persistence_store": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="agents_store.db", - ), - "responses_store": SqliteSqlStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="responses_store.db", - ), + "persistence": { + "agent_state": KVStoreReference( + backend="kv_default", + namespace="agents", + ).model_dump(exclude_none=True), + "responses": ResponsesStoreReference( + backend="sql_default", + table_name="responses", + ).model_dump(exclude_none=True), + } } diff --git a/llama_stack/providers/inline/agents/meta_reference/responses/openai_responses.py b/llama_stack/providers/inline/agents/meta_reference/responses/openai_responses.py index 851e6ef28..2360dafd9 100644 --- a/llama_stack/providers/inline/agents/meta_reference/responses/openai_responses.py +++ b/llama_stack/providers/inline/agents/meta_reference/responses/openai_responses.py @@ -359,6 +359,7 @@ class OpenAIResponsesImpl: tool_executor=self.tool_executor, safety_api=self.safety_api, guardrail_ids=guardrail_ids, + instructions=instructions, ) # Stream the response diff --git a/llama_stack/providers/inline/agents/meta_reference/responses/streaming.py b/llama_stack/providers/inline/agents/meta_reference/responses/streaming.py index caf899cdd..e80ffcdd1 100644 --- a/llama_stack/providers/inline/agents/meta_reference/responses/streaming.py +++ b/llama_stack/providers/inline/agents/meta_reference/responses/streaming.py @@ -110,6 +110,7 @@ class StreamingResponseOrchestrator: text: OpenAIResponseText, max_infer_iters: int, tool_executor, # Will be the tool execution logic from the main class + instructions: str, safety_api, guardrail_ids: list[str] | None = None, ): @@ -133,6 +134,8 @@ class StreamingResponseOrchestrator: self.accumulated_usage: OpenAIResponseUsage | None = None # Track if we've sent a refusal response self.violation_detected = False + # system message that is inserted into the model's context + self.instructions = instructions async def _create_refusal_response(self, violation_message: str) -> OpenAIResponseObjectStream: """Create a refusal response to replace streaming content.""" @@ -176,6 +179,7 @@ class StreamingResponseOrchestrator: tools=self.ctx.available_tools(), error=error, usage=self.accumulated_usage, + instructions=self.instructions, ) async def create_response(self) -> AsyncIterator[OpenAIResponseObjectStream]: diff --git a/llama_stack/providers/inline/batches/reference/config.py b/llama_stack/providers/inline/batches/reference/config.py index d8d06868b..f896a897d 100644 --- a/llama_stack/providers/inline/batches/reference/config.py +++ b/llama_stack/providers/inline/batches/reference/config.py @@ -6,13 +6,13 @@ from pydantic import BaseModel, Field -from llama_stack.providers.utils.kvstore.config import KVStoreConfig, SqliteKVStoreConfig +from llama_stack.core.storage.datatypes import KVStoreReference class ReferenceBatchesImplConfig(BaseModel): """Configuration for the Reference Batches implementation.""" - kvstore: KVStoreConfig = Field( + kvstore: KVStoreReference = Field( description="Configuration for the key-value store backend.", ) @@ -33,8 +33,8 @@ class ReferenceBatchesImplConfig(BaseModel): @classmethod def sample_run_config(cls, __distro_dir__: str) -> dict: return { - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="batches.db", - ), + "kvstore": KVStoreReference( + backend="kv_default", + namespace="batches", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/inline/datasetio/localfs/config.py b/llama_stack/providers/inline/datasetio/localfs/config.py index b450e8777..6e878df62 100644 --- a/llama_stack/providers/inline/datasetio/localfs/config.py +++ b/llama_stack/providers/inline/datasetio/localfs/config.py @@ -7,20 +7,17 @@ from typing import Any from pydantic import BaseModel -from llama_stack.providers.utils.kvstore.config import ( - KVStoreConfig, - SqliteKVStoreConfig, -) +from llama_stack.core.storage.datatypes import KVStoreReference class LocalFSDatasetIOConfig(BaseModel): - kvstore: KVStoreConfig + kvstore: KVStoreReference @classmethod def sample_run_config(cls, __distro_dir__: str, **kwargs: Any) -> dict[str, Any]: return { - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="localfs_datasetio.db", - ) + "kvstore": KVStoreReference( + backend="kv_default", + namespace="datasetio::localfs", + ).model_dump(exclude_none=True) } diff --git a/llama_stack/providers/inline/eval/meta_reference/config.py b/llama_stack/providers/inline/eval/meta_reference/config.py index 2a4a29998..b496c855e 100644 --- a/llama_stack/providers/inline/eval/meta_reference/config.py +++ b/llama_stack/providers/inline/eval/meta_reference/config.py @@ -7,20 +7,17 @@ from typing import Any from pydantic import BaseModel -from llama_stack.providers.utils.kvstore.config import ( - KVStoreConfig, - SqliteKVStoreConfig, -) +from llama_stack.core.storage.datatypes import KVStoreReference class MetaReferenceEvalConfig(BaseModel): - kvstore: KVStoreConfig + kvstore: KVStoreReference @classmethod def sample_run_config(cls, __distro_dir__: str, **kwargs: Any) -> dict[str, Any]: return { - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="meta_reference_eval.db", - ) + "kvstore": KVStoreReference( + backend="kv_default", + namespace="eval", + ).model_dump(exclude_none=True) } diff --git a/llama_stack/providers/inline/files/localfs/config.py b/llama_stack/providers/inline/files/localfs/config.py index 6c767af8f..0c2dd3b21 100644 --- a/llama_stack/providers/inline/files/localfs/config.py +++ b/llama_stack/providers/inline/files/localfs/config.py @@ -8,14 +8,14 @@ from typing import Any from pydantic import BaseModel, Field -from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig, SqlStoreConfig +from llama_stack.core.storage.datatypes import SqlStoreReference class LocalfsFilesImplConfig(BaseModel): storage_dir: str = Field( description="Directory to store uploaded files", ) - metadata_store: SqlStoreConfig = Field( + metadata_store: SqlStoreReference = Field( description="SQL store configuration for file metadata", ) ttl_secs: int = 365 * 24 * 60 * 60 # 1 year @@ -24,8 +24,8 @@ class LocalfsFilesImplConfig(BaseModel): def sample_run_config(cls, __distro_dir__: str) -> dict[str, Any]: return { "storage_dir": "${env.FILES_STORAGE_DIR:=" + __distro_dir__ + "/files}", - "metadata_store": SqliteSqlStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="files_metadata.db", - ), + "metadata_store": SqlStoreReference( + backend="sql_default", + table_name="files_metadata", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/inline/inference/sentence_transformers/sentence_transformers.py b/llama_stack/providers/inline/inference/sentence_transformers/sentence_transformers.py index 871adcb24..cb72aa13a 100644 --- a/llama_stack/providers/inline/inference/sentence_transformers/sentence_transformers.py +++ b/llama_stack/providers/inline/inference/sentence_transformers/sentence_transformers.py @@ -59,7 +59,6 @@ class SentenceTransformersInferenceImpl( provider_id=self.__provider_id__, metadata={ "embedding_dimension": 768, - "default_configured": True, }, model_type=ModelType.embedding, ), diff --git a/llama_stack/providers/inline/telemetry/meta_reference/console_span_processor.py b/llama_stack/providers/inline/telemetry/meta_reference/console_span_processor.py deleted file mode 100644 index 78e49af94..000000000 --- a/llama_stack/providers/inline/telemetry/meta_reference/console_span_processor.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under the terms described in the LICENSE file in -# the root directory of this source tree. - -import json -from datetime import UTC, datetime - -from opentelemetry.sdk.trace import ReadableSpan -from opentelemetry.sdk.trace.export import SpanProcessor -from opentelemetry.trace.status import StatusCode - -from llama_stack.log import get_logger - -logger = get_logger(name="console_span_processor", category="telemetry") - - -class ConsoleSpanProcessor(SpanProcessor): - def __init__(self, print_attributes: bool = False): - self.print_attributes = print_attributes - - def on_start(self, span: ReadableSpan, parent_context=None) -> None: - if span.attributes and span.attributes.get("__autotraced__"): - return - - timestamp = datetime.fromtimestamp(span.start_time / 1e9, tz=UTC).strftime("%H:%M:%S.%f")[:-3] - logger.info(f"[dim]{timestamp}[/dim] [bold magenta][START][/bold magenta] [dim]{span.name}[/dim]") - - def on_end(self, span: ReadableSpan) -> None: - timestamp = datetime.fromtimestamp(span.end_time / 1e9, tz=UTC).strftime("%H:%M:%S.%f")[:-3] - span_context = f"[dim]{timestamp}[/dim] [bold magenta][END][/bold magenta] [dim]{span.name}[/dim]" - if span.status.status_code == StatusCode.ERROR: - span_context += " [bold red][ERROR][/bold red]" - elif span.status.status_code != StatusCode.UNSET: - span_context += f" [{span.status.status_code}]" - duration_ms = (span.end_time - span.start_time) / 1e6 - span_context += f" ({duration_ms:.2f}ms)" - logger.info(span_context) - - if self.print_attributes and span.attributes: - for key, value in span.attributes.items(): - if key.startswith("__"): - continue - str_value = str(value) - if len(str_value) > 1000: - str_value = str_value[:997] + "..." - logger.info(f" [dim]{key}[/dim]: {str_value}") - - for event in span.events: - event_time = datetime.fromtimestamp(event.timestamp / 1e9, tz=UTC).strftime("%H:%M:%S.%f")[:-3] - severity = event.attributes.get("severity", "info") - message = event.attributes.get("message", event.name) - if isinstance(message, dict) or isinstance(message, list): - message = json.dumps(message, indent=2) - severity_color = { - "error": "red", - "warn": "yellow", - "info": "white", - "debug": "dim", - }.get(severity, "white") - logger.info(f" {event_time} [bold {severity_color}][{severity.upper()}][/bold {severity_color}] {message}") - if event.attributes: - for key, value in event.attributes.items(): - if key.startswith("__") or key in ["message", "severity"]: - continue - logger.info(f"[dim]{key}[/dim]: {value}") - - def shutdown(self) -> None: - """Shutdown the processor.""" - pass - - def force_flush(self, timeout_millis: float | None = None) -> bool: - """Force flush any pending spans.""" - return True diff --git a/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py b/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py index 2a225476b..b15b1e490 100644 --- a/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py +++ b/llama_stack/providers/inline/telemetry/meta_reference/telemetry.py @@ -79,8 +79,10 @@ class TelemetryAdapter(Telemetry): metric_reader = PeriodicExportingMetricReader(OTLPMetricExporter()) metric_provider = MeterProvider(metric_readers=[metric_reader]) metrics.set_meter_provider(metric_provider) + self.is_otel_endpoint_set = True else: logger.warning("OTEL_EXPORTER_OTLP_ENDPOINT is not set, skipping telemetry") + self.is_otel_endpoint_set = False self.meter = metrics.get_meter(__name__) self._lock = _global_lock @@ -89,7 +91,8 @@ class TelemetryAdapter(Telemetry): pass async def shutdown(self) -> None: - trace.get_tracer_provider().force_flush() + if self.is_otel_endpoint_set: + trace.get_tracer_provider().force_flush() async def log_event(self, event: Event, ttl_seconds: int = 604800) -> None: if isinstance(event, UnstructuredLogEvent): diff --git a/llama_stack/providers/inline/vector_io/chroma/__init__.py b/llama_stack/providers/inline/vector_io/chroma/__init__.py index 09e869c90..575e5ad88 100644 --- a/llama_stack/providers/inline/vector_io/chroma/__init__.py +++ b/llama_stack/providers/inline/vector_io/chroma/__init__.py @@ -12,15 +12,8 @@ from .config import ChromaVectorIOConfig async def get_provider_impl(config: ChromaVectorIOConfig, deps: dict[Api, Any]): - from llama_stack.providers.remote.vector_io.chroma.chroma import ( - ChromaVectorIOAdapter, - ) + from llama_stack.providers.remote.vector_io.chroma.chroma import ChromaVectorIOAdapter - impl = ChromaVectorIOAdapter( - config, - deps[Api.inference], - deps[Api.models], - deps.get(Api.files), - ) + impl = ChromaVectorIOAdapter(config, deps[Api.inference], deps.get(Api.files)) await impl.initialize() return impl diff --git a/llama_stack/providers/inline/vector_io/chroma/config.py b/llama_stack/providers/inline/vector_io/chroma/config.py index a9566f7ff..1798f10de 100644 --- a/llama_stack/providers/inline/vector_io/chroma/config.py +++ b/llama_stack/providers/inline/vector_io/chroma/config.py @@ -8,14 +8,14 @@ from typing import Any from pydantic import BaseModel, Field -from llama_stack.providers.utils.kvstore.config import KVStoreConfig, SqliteKVStoreConfig +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.schema_utils import json_schema_type @json_schema_type class ChromaVectorIOConfig(BaseModel): db_path: str - kvstore: KVStoreConfig = Field(description="Config for KV store backend") + persistence: KVStoreReference = Field(description="Config for KV store backend") @classmethod def sample_run_config( @@ -23,8 +23,8 @@ class ChromaVectorIOConfig(BaseModel): ) -> dict[str, Any]: return { "db_path": db_path, - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="chroma_inline_registry.db", - ), + "persistence": KVStoreReference( + backend="kv_default", + namespace="vector_io::chroma", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/inline/vector_io/faiss/__init__.py b/llama_stack/providers/inline/vector_io/faiss/__init__.py index c0f01bc9d..24d1f292a 100644 --- a/llama_stack/providers/inline/vector_io/faiss/__init__.py +++ b/llama_stack/providers/inline/vector_io/faiss/__init__.py @@ -16,11 +16,6 @@ async def get_provider_impl(config: FaissVectorIOConfig, deps: dict[Api, Any]): assert isinstance(config, FaissVectorIOConfig), f"Unexpected config type: {type(config)}" - impl = FaissVectorIOAdapter( - config, - deps[Api.inference], - deps[Api.models], - deps.get(Api.files), - ) + impl = FaissVectorIOAdapter(config, deps[Api.inference], deps.get(Api.files)) await impl.initialize() return impl diff --git a/llama_stack/providers/inline/vector_io/faiss/config.py b/llama_stack/providers/inline/vector_io/faiss/config.py index cbcbb1762..dd7a7aeca 100644 --- a/llama_stack/providers/inline/vector_io/faiss/config.py +++ b/llama_stack/providers/inline/vector_io/faiss/config.py @@ -8,22 +8,19 @@ from typing import Any from pydantic import BaseModel -from llama_stack.providers.utils.kvstore.config import ( - KVStoreConfig, - SqliteKVStoreConfig, -) +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.schema_utils import json_schema_type @json_schema_type class FaissVectorIOConfig(BaseModel): - kvstore: KVStoreConfig + persistence: KVStoreReference @classmethod def sample_run_config(cls, __distro_dir__: str, **kwargs: Any) -> dict[str, Any]: return { - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="faiss_store.db", - ) + "persistence": KVStoreReference( + backend="kv_default", + namespace="vector_io::faiss", + ).model_dump(exclude_none=True) } diff --git a/llama_stack/providers/inline/vector_io/faiss/faiss.py b/llama_stack/providers/inline/vector_io/faiss/faiss.py index df0864db8..5e33d4ca3 100644 --- a/llama_stack/providers/inline/vector_io/faiss/faiss.py +++ b/llama_stack/providers/inline/vector_io/faiss/faiss.py @@ -17,34 +17,21 @@ from numpy.typing import NDArray from llama_stack.apis.common.errors import VectorStoreNotFoundError from llama_stack.apis.files import Files from llama_stack.apis.inference import Inference, InterleavedContent -from llama_stack.apis.models import Models -from llama_stack.apis.vector_dbs import VectorDB -from llama_stack.apis.vector_io import ( - Chunk, - QueryChunksResponse, - VectorIO, -) +from llama_stack.apis.vector_io import Chunk, QueryChunksResponse, VectorIO +from llama_stack.apis.vector_stores import VectorStore from llama_stack.log import get_logger -from llama_stack.providers.datatypes import ( - HealthResponse, - HealthStatus, - VectorDBsProtocolPrivate, -) +from llama_stack.providers.datatypes import HealthResponse, HealthStatus, VectorStoresProtocolPrivate from llama_stack.providers.utils.kvstore import kvstore_impl from llama_stack.providers.utils.kvstore.api import KVStore from llama_stack.providers.utils.memory.openai_vector_store_mixin import OpenAIVectorStoreMixin -from llama_stack.providers.utils.memory.vector_store import ( - ChunkForDeletion, - EmbeddingIndex, - VectorDBWithIndex, -) +from llama_stack.providers.utils.memory.vector_store import ChunkForDeletion, EmbeddingIndex, VectorStoreWithIndex from .config import FaissVectorIOConfig logger = get_logger(name=__name__, category="vector_io") VERSION = "v3" -VECTOR_DBS_PREFIX = f"vector_dbs:{VERSION}::" +VECTOR_DBS_PREFIX = f"vector_stores:{VERSION}::" FAISS_INDEX_PREFIX = f"faiss_index:{VERSION}::" OPENAI_VECTOR_STORES_PREFIX = f"openai_vector_stores:{VERSION}::" OPENAI_VECTOR_STORES_FILES_PREFIX = f"openai_vector_stores_files:{VERSION}::" @@ -155,12 +142,7 @@ class FaissIndex(EmbeddingIndex): await self._save_index() - async def query_vector( - self, - embedding: NDArray, - k: int, - score_threshold: float, - ) -> QueryChunksResponse: + async def query_vector(self, embedding: NDArray, k: int, score_threshold: float) -> QueryChunksResponse: distances, indices = await asyncio.to_thread(self.index.search, embedding.reshape(1, -1).astype(np.float32), k) chunks = [] scores = [] @@ -175,12 +157,7 @@ class FaissIndex(EmbeddingIndex): return QueryChunksResponse(chunks=chunks, scores=scores) - async def query_keyword( - self, - query_string: str, - k: int, - score_threshold: float, - ) -> QueryChunksResponse: + async def query_keyword(self, query_string: str, k: int, score_threshold: float) -> QueryChunksResponse: raise NotImplementedError( "Keyword search is not supported - underlying DB FAISS does not support this search mode" ) @@ -199,35 +176,28 @@ class FaissIndex(EmbeddingIndex): ) -class FaissVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolPrivate): - def __init__( - self, - config: FaissVectorIOConfig, - inference_api: Inference, - models_api: Models, - files_api: Files | None, - ) -> None: +class FaissVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorStoresProtocolPrivate): + def __init__(self, config: FaissVectorIOConfig, inference_api: Inference, files_api: Files | None) -> None: super().__init__(files_api=files_api, kvstore=None) self.config = config self.inference_api = inference_api - self.models_api = models_api - self.cache: dict[str, VectorDBWithIndex] = {} + self.cache: dict[str, VectorStoreWithIndex] = {} async def initialize(self) -> None: - self.kvstore = await kvstore_impl(self.config.kvstore) + self.kvstore = await kvstore_impl(self.config.persistence) # Load existing banks from kvstore start_key = VECTOR_DBS_PREFIX end_key = f"{VECTOR_DBS_PREFIX}\xff" - stored_vector_dbs = await self.kvstore.values_in_range(start_key, end_key) + stored_vector_stores = await self.kvstore.values_in_range(start_key, end_key) - for vector_db_data in stored_vector_dbs: - vector_db = VectorDB.model_validate_json(vector_db_data) - index = VectorDBWithIndex( - vector_db, - await FaissIndex.create(vector_db.embedding_dimension, self.kvstore, vector_db.identifier), + for vector_store_data in stored_vector_stores: + vector_store = VectorStore.model_validate_json(vector_store_data) + index = VectorStoreWithIndex( + vector_store, + await FaissIndex.create(vector_store.embedding_dimension, self.kvstore, vector_store.identifier), self.inference_api, ) - self.cache[vector_db.identifier] = index + self.cache[vector_store.identifier] = index # Load existing OpenAI vector stores into the in-memory cache await self.initialize_openai_vector_stores() @@ -252,45 +222,33 @@ class FaissVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolPr except Exception as e: return HealthResponse(status=HealthStatus.ERROR, message=f"Health check failed: {str(e)}") - async def register_vector_db( - self, - vector_db: VectorDB, - ) -> None: + async def register_vector_store(self, vector_store: VectorStore) -> None: assert self.kvstore is not None - key = f"{VECTOR_DBS_PREFIX}{vector_db.identifier}" - await self.kvstore.set( - key=key, - value=vector_db.model_dump_json(), - ) + key = f"{VECTOR_DBS_PREFIX}{vector_store.identifier}" + await self.kvstore.set(key=key, value=vector_store.model_dump_json()) # Store in cache - self.cache[vector_db.identifier] = VectorDBWithIndex( - vector_db=vector_db, - index=await FaissIndex.create(vector_db.embedding_dimension, self.kvstore, vector_db.identifier), + self.cache[vector_store.identifier] = VectorStoreWithIndex( + vector_store=vector_store, + index=await FaissIndex.create(vector_store.embedding_dimension, self.kvstore, vector_store.identifier), inference_api=self.inference_api, ) - async def list_vector_dbs(self) -> list[VectorDB]: - return [i.vector_db for i in self.cache.values()] + async def list_vector_stores(self) -> list[VectorStore]: + return [i.vector_store for i in self.cache.values()] - async def unregister_vector_db(self, vector_db_id: str) -> None: + async def unregister_vector_store(self, vector_store_id: str) -> None: assert self.kvstore is not None - if vector_db_id not in self.cache: - logger.warning(f"Vector DB {vector_db_id} not found") + if vector_store_id not in self.cache: return - await self.cache[vector_db_id].index.delete() - del self.cache[vector_db_id] - await self.kvstore.delete(f"{VECTOR_DBS_PREFIX}{vector_db_id}") + await self.cache[vector_store_id].index.delete() + del self.cache[vector_store_id] + await self.kvstore.delete(f"{VECTOR_DBS_PREFIX}{vector_store_id}") - async def insert_chunks( - self, - vector_db_id: str, - chunks: list[Chunk], - ttl_seconds: int | None = None, - ) -> None: + async def insert_chunks(self, vector_db_id: str, chunks: list[Chunk], ttl_seconds: int | None = None) -> None: index = self.cache.get(vector_db_id) if index is None: raise ValueError(f"Vector DB {vector_db_id} not found. found: {self.cache.keys()}") @@ -298,10 +256,7 @@ class FaissVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolPr await index.insert_chunks(chunks) async def query_chunks( - self, - vector_db_id: str, - query: InterleavedContent, - params: dict[str, Any] | None = None, + self, vector_db_id: str, query: InterleavedContent, params: dict[str, Any] | None = None ) -> QueryChunksResponse: index = self.cache.get(vector_db_id) if index is None: diff --git a/llama_stack/providers/inline/vector_io/milvus/__init__.py b/llama_stack/providers/inline/vector_io/milvus/__init__.py index 46a006a91..7dc9c6a33 100644 --- a/llama_stack/providers/inline/vector_io/milvus/__init__.py +++ b/llama_stack/providers/inline/vector_io/milvus/__init__.py @@ -14,11 +14,6 @@ from .config import MilvusVectorIOConfig async def get_provider_impl(config: MilvusVectorIOConfig, deps: dict[Api, Any]): from llama_stack.providers.remote.vector_io.milvus.milvus import MilvusVectorIOAdapter - impl = MilvusVectorIOAdapter( - config, - deps[Api.inference], - deps[Api.models], - deps.get(Api.files), - ) + impl = MilvusVectorIOAdapter(config, deps[Api.inference], deps.get(Api.files)) await impl.initialize() return impl diff --git a/llama_stack/providers/inline/vector_io/milvus/config.py b/llama_stack/providers/inline/vector_io/milvus/config.py index 8cbd056be..b333b04ea 100644 --- a/llama_stack/providers/inline/vector_io/milvus/config.py +++ b/llama_stack/providers/inline/vector_io/milvus/config.py @@ -8,25 +8,22 @@ from typing import Any from pydantic import BaseModel, Field -from llama_stack.providers.utils.kvstore.config import ( - KVStoreConfig, - SqliteKVStoreConfig, -) +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.schema_utils import json_schema_type @json_schema_type class MilvusVectorIOConfig(BaseModel): db_path: str - kvstore: KVStoreConfig = Field(description="Config for KV store backend (SQLite only for now)") + persistence: KVStoreReference = Field(description="Config for KV store backend (SQLite only for now)") consistency_level: str = Field(description="The consistency level of the Milvus server", default="Strong") @classmethod def sample_run_config(cls, __distro_dir__: str, **kwargs: Any) -> dict[str, Any]: return { "db_path": "${env.MILVUS_DB_PATH:=" + __distro_dir__ + "}/" + "milvus.db", - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="milvus_registry.db", - ), + "persistence": KVStoreReference( + backend="kv_default", + namespace="vector_io::milvus", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/inline/vector_io/qdrant/__init__.py b/llama_stack/providers/inline/vector_io/qdrant/__init__.py index 2863f667c..bef6d50e6 100644 --- a/llama_stack/providers/inline/vector_io/qdrant/__init__.py +++ b/llama_stack/providers/inline/vector_io/qdrant/__init__.py @@ -15,11 +15,6 @@ async def get_provider_impl(config: QdrantVectorIOConfig, deps: dict[Api, Any]): from llama_stack.providers.remote.vector_io.qdrant.qdrant import QdrantVectorIOAdapter assert isinstance(config, QdrantVectorIOConfig), f"Unexpected config type: {type(config)}" - impl = QdrantVectorIOAdapter( - config, - deps[Api.inference], - deps[Api.models], - deps.get(Api.files), - ) + impl = QdrantVectorIOAdapter(config, deps[Api.inference], deps.get(Api.files)) await impl.initialize() return impl diff --git a/llama_stack/providers/inline/vector_io/qdrant/config.py b/llama_stack/providers/inline/vector_io/qdrant/config.py index e15c27ea1..e7ecde7b7 100644 --- a/llama_stack/providers/inline/vector_io/qdrant/config.py +++ b/llama_stack/providers/inline/vector_io/qdrant/config.py @@ -9,23 +9,21 @@ from typing import Any from pydantic import BaseModel -from llama_stack.providers.utils.kvstore.config import ( - KVStoreConfig, - SqliteKVStoreConfig, -) +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.schema_utils import json_schema_type @json_schema_type class QdrantVectorIOConfig(BaseModel): path: str - kvstore: KVStoreConfig + persistence: KVStoreReference @classmethod def sample_run_config(cls, __distro_dir__: str) -> dict[str, Any]: return { "path": "${env.QDRANT_PATH:=~/.llama/" + __distro_dir__ + "}/" + "qdrant.db", - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, db_name="qdrant_registry.db" - ), + "persistence": KVStoreReference( + backend="kv_default", + namespace="vector_io::qdrant", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/inline/vector_io/sqlite_vec/__init__.py b/llama_stack/providers/inline/vector_io/sqlite_vec/__init__.py index 93921fb23..df96e927c 100644 --- a/llama_stack/providers/inline/vector_io/sqlite_vec/__init__.py +++ b/llama_stack/providers/inline/vector_io/sqlite_vec/__init__.py @@ -15,11 +15,6 @@ async def get_provider_impl(config: SQLiteVectorIOConfig, deps: dict[Api, Any]): from .sqlite_vec import SQLiteVecVectorIOAdapter assert isinstance(config, SQLiteVectorIOConfig), f"Unexpected config type: {type(config)}" - impl = SQLiteVecVectorIOAdapter( - config, - deps[Api.inference], - deps[Api.models], - deps.get(Api.files), - ) + impl = SQLiteVecVectorIOAdapter(config, deps[Api.inference], deps.get(Api.files)) await impl.initialize() return impl diff --git a/llama_stack/providers/inline/vector_io/sqlite_vec/config.py b/llama_stack/providers/inline/vector_io/sqlite_vec/config.py index 525ed4b1f..596f8fc95 100644 --- a/llama_stack/providers/inline/vector_io/sqlite_vec/config.py +++ b/llama_stack/providers/inline/vector_io/sqlite_vec/config.py @@ -8,22 +8,19 @@ from typing import Any from pydantic import BaseModel, Field -from llama_stack.providers.utils.kvstore.config import ( - KVStoreConfig, - SqliteKVStoreConfig, -) +from llama_stack.core.storage.datatypes import KVStoreReference class SQLiteVectorIOConfig(BaseModel): db_path: str = Field(description="Path to the SQLite database file") - kvstore: KVStoreConfig = Field(description="Config for KV store backend (SQLite only for now)") + persistence: KVStoreReference = Field(description="Config for KV store backend (SQLite only for now)") @classmethod def sample_run_config(cls, __distro_dir__: str) -> dict[str, Any]: return { "db_path": "${env.SQLITE_STORE_DIR:=" + __distro_dir__ + "}/" + "sqlite_vec.db", - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="sqlite_vec_registry.db", - ), + "persistence": KVStoreReference( + backend="kv_default", + namespace="vector_io::sqlite_vec", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/inline/vector_io/sqlite_vec/sqlite_vec.py b/llama_stack/providers/inline/vector_io/sqlite_vec/sqlite_vec.py index 8bc3b04cb..37294f173 100644 --- a/llama_stack/providers/inline/vector_io/sqlite_vec/sqlite_vec.py +++ b/llama_stack/providers/inline/vector_io/sqlite_vec/sqlite_vec.py @@ -17,15 +17,10 @@ from numpy.typing import NDArray from llama_stack.apis.common.errors import VectorStoreNotFoundError from llama_stack.apis.files import Files from llama_stack.apis.inference import Inference -from llama_stack.apis.models import Models -from llama_stack.apis.vector_dbs import VectorDB -from llama_stack.apis.vector_io import ( - Chunk, - QueryChunksResponse, - VectorIO, -) +from llama_stack.apis.vector_io import Chunk, QueryChunksResponse, VectorIO +from llama_stack.apis.vector_stores import VectorStore from llama_stack.log import get_logger -from llama_stack.providers.datatypes import VectorDBsProtocolPrivate +from llama_stack.providers.datatypes import VectorStoresProtocolPrivate from llama_stack.providers.utils.kvstore import kvstore_impl from llama_stack.providers.utils.kvstore.api import KVStore from llama_stack.providers.utils.memory.openai_vector_store_mixin import OpenAIVectorStoreMixin @@ -33,7 +28,7 @@ from llama_stack.providers.utils.memory.vector_store import ( RERANKER_TYPE_RRF, ChunkForDeletion, EmbeddingIndex, - VectorDBWithIndex, + VectorStoreWithIndex, ) from llama_stack.providers.utils.vector_io.vector_utils import WeightedInMemoryAggregator @@ -46,7 +41,7 @@ HYBRID_SEARCH = "hybrid" SEARCH_MODES = {VECTOR_SEARCH, KEYWORD_SEARCH, HYBRID_SEARCH} VERSION = "v3" -VECTOR_DBS_PREFIX = f"vector_dbs:sqlite_vec:{VERSION}::" +VECTOR_DBS_PREFIX = f"vector_stores:sqlite_vec:{VERSION}::" VECTOR_INDEX_PREFIX = f"vector_index:sqlite_vec:{VERSION}::" OPENAI_VECTOR_STORES_PREFIX = f"openai_vector_stores:sqlite_vec:{VERSION}::" OPENAI_VECTOR_STORES_FILES_PREFIX = f"openai_vector_stores_files:sqlite_vec:{VERSION}::" @@ -175,32 +170,18 @@ class SQLiteVecIndex(EmbeddingIndex): # Insert vector embeddings embedding_data = [ - ( - ( - chunk.chunk_id, - serialize_vector(emb.tolist()), - ) - ) + ((chunk.chunk_id, serialize_vector(emb.tolist()))) for chunk, emb in zip(batch_chunks, batch_embeddings, strict=True) ] - cur.executemany( - f"INSERT INTO [{self.vector_table}] (id, embedding) VALUES (?, ?);", - embedding_data, - ) + cur.executemany(f"INSERT INTO [{self.vector_table}] (id, embedding) VALUES (?, ?);", embedding_data) # Insert FTS content fts_data = [(chunk.chunk_id, chunk.content) for chunk in batch_chunks] # DELETE existing entries with same IDs (FTS5 doesn't support ON CONFLICT) - cur.executemany( - f"DELETE FROM [{self.fts_table}] WHERE id = ?;", - [(row[0],) for row in fts_data], - ) + cur.executemany(f"DELETE FROM [{self.fts_table}] WHERE id = ?;", [(row[0],) for row in fts_data]) # INSERT new entries - cur.executemany( - f"INSERT INTO [{self.fts_table}] (id, content) VALUES (?, ?);", - fts_data, - ) + cur.executemany(f"INSERT INTO [{self.fts_table}] (id, content) VALUES (?, ?);", fts_data) connection.commit() @@ -216,12 +197,7 @@ class SQLiteVecIndex(EmbeddingIndex): # Run batch insertion in a background thread await asyncio.to_thread(_execute_all_batch_inserts) - async def query_vector( - self, - embedding: NDArray, - k: int, - score_threshold: float, - ) -> QueryChunksResponse: + async def query_vector(self, embedding: NDArray, k: int, score_threshold: float) -> QueryChunksResponse: """ Performs vector-based search using a virtual table for vector similarity. """ @@ -261,12 +237,7 @@ class SQLiteVecIndex(EmbeddingIndex): scores.append(score) return QueryChunksResponse(chunks=chunks, scores=scores) - async def query_keyword( - self, - query_string: str, - k: int, - score_threshold: float, - ) -> QueryChunksResponse: + async def query_keyword(self, query_string: str, k: int, score_threshold: float) -> QueryChunksResponse: """ Performs keyword-based search using SQLite FTS5 for relevance-ranked full-text search. """ @@ -403,41 +374,32 @@ class SQLiteVecIndex(EmbeddingIndex): await asyncio.to_thread(_delete_chunks) -class SQLiteVecVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolPrivate): +class SQLiteVecVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorStoresProtocolPrivate): """ A VectorIO implementation using SQLite + sqlite_vec. - This class handles vector database registration (with metadata stored in a table named `vector_dbs`) - and creates a cache of VectorDBWithIndex instances (each wrapping a SQLiteVecIndex). + This class handles vector database registration (with metadata stored in a table named `vector_stores`) + and creates a cache of VectorStoreWithIndex instances (each wrapping a SQLiteVecIndex). """ - def __init__( - self, - config, - inference_api: Inference, - models_api: Models, - files_api: Files | None, - ) -> None: + def __init__(self, config, inference_api: Inference, files_api: Files | None) -> None: super().__init__(files_api=files_api, kvstore=None) self.config = config self.inference_api = inference_api - self.models_api = models_api - self.cache: dict[str, VectorDBWithIndex] = {} - self.vector_db_store = None + self.cache: dict[str, VectorStoreWithIndex] = {} + self.vector_store_table = None async def initialize(self) -> None: - self.kvstore = await kvstore_impl(self.config.kvstore) + self.kvstore = await kvstore_impl(self.config.persistence) start_key = VECTOR_DBS_PREFIX end_key = f"{VECTOR_DBS_PREFIX}\xff" - stored_vector_dbs = await self.kvstore.values_in_range(start_key, end_key) - for db_json in stored_vector_dbs: - vector_db = VectorDB.model_validate_json(db_json) + stored_vector_stores = await self.kvstore.values_in_range(start_key, end_key) + for db_json in stored_vector_stores: + vector_store = VectorStore.model_validate_json(db_json) index = await SQLiteVecIndex.create( - vector_db.embedding_dimension, - self.config.db_path, - vector_db.identifier, + vector_store.embedding_dimension, self.config.db_path, vector_store.identifier ) - self.cache[vector_db.identifier] = VectorDBWithIndex(vector_db, index, self.inference_api) + self.cache[vector_store.identifier] = VectorStoreWithIndex(vector_store, index, self.inference_api) # Load existing OpenAI vector stores into the in-memory cache await self.initialize_openai_vector_stores() @@ -446,67 +408,64 @@ class SQLiteVecVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtoc # Clean up mixin resources (file batch tasks) await super().shutdown() - async def list_vector_dbs(self) -> list[VectorDB]: - return [v.vector_db for v in self.cache.values()] + async def list_vector_stores(self) -> list[VectorStore]: + return [v.vector_store for v in self.cache.values()] - async def register_vector_db(self, vector_db: VectorDB) -> None: + async def register_vector_store(self, vector_store: VectorStore) -> None: index = await SQLiteVecIndex.create( - vector_db.embedding_dimension, - self.config.db_path, - vector_db.identifier, + vector_store.embedding_dimension, self.config.db_path, vector_store.identifier ) - self.cache[vector_db.identifier] = VectorDBWithIndex(vector_db, index, self.inference_api) + self.cache[vector_store.identifier] = VectorStoreWithIndex(vector_store, index, self.inference_api) - async def _get_and_cache_vector_db_index(self, vector_db_id: str) -> VectorDBWithIndex | None: - if vector_db_id in self.cache: - return self.cache[vector_db_id] + async def _get_and_cache_vector_store_index(self, vector_store_id: str) -> VectorStoreWithIndex | None: + if vector_store_id in self.cache: + return self.cache[vector_store_id] - if self.vector_db_store is None: - raise VectorStoreNotFoundError(vector_db_id) + if self.vector_store_table is None: + raise VectorStoreNotFoundError(vector_store_id) - vector_db = self.vector_db_store.get_vector_db(vector_db_id) - if not vector_db: - raise VectorStoreNotFoundError(vector_db_id) + vector_store = self.vector_store_table.get_vector_store(vector_store_id) + if not vector_store: + raise VectorStoreNotFoundError(vector_store_id) - index = VectorDBWithIndex( - vector_db=vector_db, + index = VectorStoreWithIndex( + vector_store=vector_store, index=SQLiteVecIndex( - dimension=vector_db.embedding_dimension, + dimension=vector_store.embedding_dimension, db_path=self.config.db_path, - bank_id=vector_db.identifier, + bank_id=vector_store.identifier, kvstore=self.kvstore, ), inference_api=self.inference_api, ) - self.cache[vector_db_id] = index + self.cache[vector_store_id] = index return index - async def unregister_vector_db(self, vector_db_id: str) -> None: - if vector_db_id not in self.cache: - logger.warning(f"Vector DB {vector_db_id} not found") + async def unregister_vector_store(self, vector_store_id: str) -> None: + if vector_store_id not in self.cache: return - await self.cache[vector_db_id].index.delete() - del self.cache[vector_db_id] + await self.cache[vector_store_id].index.delete() + del self.cache[vector_store_id] async def insert_chunks(self, vector_db_id: str, chunks: list[Chunk], ttl_seconds: int | None = None) -> None: - index = await self._get_and_cache_vector_db_index(vector_db_id) + index = await self._get_and_cache_vector_store_index(vector_db_id) if not index: raise VectorStoreNotFoundError(vector_db_id) - # The VectorDBWithIndex helper is expected to compute embeddings via the inference_api + # The VectorStoreWithIndex helper is expected to compute embeddings via the inference_api # and then call our index's add_chunks. await index.insert_chunks(chunks) async def query_chunks( self, vector_db_id: str, query: Any, params: dict[str, Any] | None = None ) -> QueryChunksResponse: - index = await self._get_and_cache_vector_db_index(vector_db_id) + index = await self._get_and_cache_vector_store_index(vector_db_id) if not index: raise VectorStoreNotFoundError(vector_db_id) return await index.query_chunks(query, params) async def delete_chunks(self, store_id: str, chunks_for_deletion: list[ChunkForDeletion]) -> None: """Delete chunks from a sqlite_vec index.""" - index = await self._get_and_cache_vector_db_index(store_id) + index = await self._get_and_cache_vector_store_index(store_id) if not index: raise VectorStoreNotFoundError(store_id) diff --git a/llama_stack/providers/remote/datasetio/huggingface/config.py b/llama_stack/providers/remote/datasetio/huggingface/config.py index 38f933728..35297cb58 100644 --- a/llama_stack/providers/remote/datasetio/huggingface/config.py +++ b/llama_stack/providers/remote/datasetio/huggingface/config.py @@ -7,20 +7,17 @@ from typing import Any from pydantic import BaseModel -from llama_stack.providers.utils.kvstore.config import ( - KVStoreConfig, - SqliteKVStoreConfig, -) +from llama_stack.core.storage.datatypes import KVStoreReference class HuggingfaceDatasetIOConfig(BaseModel): - kvstore: KVStoreConfig + kvstore: KVStoreReference @classmethod def sample_run_config(cls, __distro_dir__: str, **kwargs: Any) -> dict[str, Any]: return { - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="huggingface_datasetio.db", - ) + "kvstore": KVStoreReference( + backend="kv_default", + namespace="datasetio::huggingface", + ).model_dump(exclude_none=True) } diff --git a/llama_stack/providers/remote/datasetio/nvidia/README.md b/llama_stack/providers/remote/datasetio/nvidia/README.md index 74e0895f4..da57d5550 100644 --- a/llama_stack/providers/remote/datasetio/nvidia/README.md +++ b/llama_stack/providers/remote/datasetio/nvidia/README.md @@ -20,7 +20,7 @@ This provider enables dataset management using NVIDIA's NeMo Customizer service. Build the NVIDIA environment: ```bash -llama stack build --distro nvidia --image-type venv +uv run llama stack list-deps nvidia | xargs -L1 uv pip install ``` ### Basic Usage using the LlamaStack Python Client diff --git a/llama_stack/providers/remote/files/s3/config.py b/llama_stack/providers/remote/files/s3/config.py index da20d8668..cd4b1adda 100644 --- a/llama_stack/providers/remote/files/s3/config.py +++ b/llama_stack/providers/remote/files/s3/config.py @@ -8,7 +8,7 @@ from typing import Any from pydantic import BaseModel, Field -from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig, SqlStoreConfig +from llama_stack.core.storage.datatypes import SqlStoreReference class S3FilesImplConfig(BaseModel): @@ -24,7 +24,7 @@ class S3FilesImplConfig(BaseModel): auto_create_bucket: bool = Field( default=False, description="Automatically create the S3 bucket if it doesn't exist" ) - metadata_store: SqlStoreConfig = Field(description="SQL store configuration for file metadata") + metadata_store: SqlStoreReference = Field(description="SQL store configuration for file metadata") @classmethod def sample_run_config(cls, __distro_dir__: str) -> dict[str, Any]: @@ -35,8 +35,8 @@ class S3FilesImplConfig(BaseModel): "aws_secret_access_key": "${env.AWS_SECRET_ACCESS_KEY:=}", "endpoint_url": "${env.S3_ENDPOINT_URL:=}", "auto_create_bucket": "${env.S3_AUTO_CREATE_BUCKET:=false}", - "metadata_store": SqliteSqlStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="s3_files_metadata.db", - ), + "metadata_store": SqlStoreReference( + backend="sql_default", + table_name="s3_files_metadata", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/remote/inference/nvidia/NVIDIA.md b/llama_stack/providers/remote/inference/nvidia/NVIDIA.md index 692b9125b..f1a828413 100644 --- a/llama_stack/providers/remote/inference/nvidia/NVIDIA.md +++ b/llama_stack/providers/remote/inference/nvidia/NVIDIA.md @@ -18,7 +18,7 @@ This provider enables running inference using NVIDIA NIM. Build the NVIDIA environment: ```bash -llama stack build --distro nvidia --image-type venv +uv run llama stack list-deps nvidia | xargs -L1 uv pip install ``` ### Basic Usage using the LlamaStack Python Client diff --git a/llama_stack/providers/remote/inference/nvidia/__init__.py b/llama_stack/providers/remote/inference/nvidia/__init__.py index 1869cb748..b4926f33e 100644 --- a/llama_stack/providers/remote/inference/nvidia/__init__.py +++ b/llama_stack/providers/remote/inference/nvidia/__init__.py @@ -10,7 +10,7 @@ from .config import NVIDIAConfig async def get_adapter_impl(config: NVIDIAConfig, _deps) -> Inference: - # import dynamically so `llama stack build` does not fail due to missing dependencies + # import dynamically so `llama stack list-deps` does not fail due to missing dependencies from .nvidia import NVIDIAInferenceAdapter if not isinstance(config, NVIDIAConfig): diff --git a/llama_stack/providers/remote/post_training/nvidia/README.md b/llama_stack/providers/remote/post_training/nvidia/README.md index 9b088a615..789514b1e 100644 --- a/llama_stack/providers/remote/post_training/nvidia/README.md +++ b/llama_stack/providers/remote/post_training/nvidia/README.md @@ -22,7 +22,7 @@ This provider enables fine-tuning of LLMs using NVIDIA's NeMo Customizer service Build the NVIDIA environment: ```bash -llama stack build --distro nvidia --image-type venv +uv run llama stack list-deps nvidia | xargs -L1 uv pip install ``` ### Basic Usage using the LlamaStack Python Client diff --git a/llama_stack/providers/remote/safety/nvidia/README.md b/llama_stack/providers/remote/safety/nvidia/README.md index 784ab464f..e589afe84 100644 --- a/llama_stack/providers/remote/safety/nvidia/README.md +++ b/llama_stack/providers/remote/safety/nvidia/README.md @@ -19,7 +19,7 @@ This provider enables safety checks and guardrails for LLM interactions using NV Build the NVIDIA environment: ```bash -llama stack build --distro nvidia --image-type venv +uv run llama stack list-deps nvidia | xargs -L1 uv pip install ``` ### Basic Usage using the LlamaStack Python Client diff --git a/llama_stack/providers/remote/vector_io/chroma/__init__.py b/llama_stack/providers/remote/vector_io/chroma/__init__.py index a6db48c43..e4b77c68d 100644 --- a/llama_stack/providers/remote/vector_io/chroma/__init__.py +++ b/llama_stack/providers/remote/vector_io/chroma/__init__.py @@ -12,11 +12,6 @@ from .config import ChromaVectorIOConfig async def get_adapter_impl(config: ChromaVectorIOConfig, deps: dict[Api, ProviderSpec]): from .chroma import ChromaVectorIOAdapter - impl = ChromaVectorIOAdapter( - config, - deps[Api.inference], - deps[Api.models], - deps.get(Api.files), - ) + impl = ChromaVectorIOAdapter(config, deps[Api.inference], deps.get(Api.files)) await impl.initialize() return impl diff --git a/llama_stack/providers/remote/vector_io/chroma/chroma.py b/llama_stack/providers/remote/vector_io/chroma/chroma.py index 5792a83c6..2663ad43e 100644 --- a/llama_stack/providers/remote/vector_io/chroma/chroma.py +++ b/llama_stack/providers/remote/vector_io/chroma/chroma.py @@ -12,24 +12,16 @@ import chromadb from numpy.typing import NDArray from llama_stack.apis.files import Files -from llama_stack.apis.inference import InterleavedContent -from llama_stack.apis.vector_dbs import VectorDB -from llama_stack.apis.vector_io import ( - Chunk, - QueryChunksResponse, - VectorIO, -) +from llama_stack.apis.inference import Inference, InterleavedContent +from llama_stack.apis.vector_io import Chunk, QueryChunksResponse, VectorIO +from llama_stack.apis.vector_stores import VectorStore from llama_stack.log import get_logger -from llama_stack.providers.datatypes import Api, VectorDBsProtocolPrivate +from llama_stack.providers.datatypes import VectorStoresProtocolPrivate from llama_stack.providers.inline.vector_io.chroma import ChromaVectorIOConfig as InlineChromaVectorIOConfig from llama_stack.providers.utils.kvstore import kvstore_impl from llama_stack.providers.utils.kvstore.api import KVStore from llama_stack.providers.utils.memory.openai_vector_store_mixin import OpenAIVectorStoreMixin -from llama_stack.providers.utils.memory.vector_store import ( - ChunkForDeletion, - EmbeddingIndex, - VectorDBWithIndex, -) +from llama_stack.providers.utils.memory.vector_store import ChunkForDeletion, EmbeddingIndex, VectorStoreWithIndex from .config import ChromaVectorIOConfig as RemoteChromaVectorIOConfig @@ -38,7 +30,7 @@ log = get_logger(name=__name__, category="vector_io::chroma") ChromaClientType = chromadb.api.AsyncClientAPI | chromadb.api.ClientAPI VERSION = "v3" -VECTOR_DBS_PREFIX = f"vector_dbs:chroma:{VERSION}::" +VECTOR_DBS_PREFIX = f"vector_stores:chroma:{VERSION}::" VECTOR_INDEX_PREFIX = f"vector_index:chroma:{VERSION}::" OPENAI_VECTOR_STORES_PREFIX = f"openai_vector_stores:chroma:{VERSION}::" OPENAI_VECTOR_STORES_FILES_PREFIX = f"openai_vector_stores_files:chroma:{VERSION}::" @@ -68,19 +60,13 @@ class ChromaIndex(EmbeddingIndex): ids = [f"{c.metadata.get('document_id', '')}:{c.chunk_id}" for c in chunks] await maybe_await( - self.collection.add( - documents=[chunk.model_dump_json() for chunk in chunks], - embeddings=embeddings, - ids=ids, - ) + self.collection.add(documents=[chunk.model_dump_json() for chunk in chunks], embeddings=embeddings, ids=ids) ) async def query_vector(self, embedding: NDArray, k: int, score_threshold: float) -> QueryChunksResponse: results = await maybe_await( self.collection.query( - query_embeddings=[embedding.tolist()], - n_results=k, - include=["documents", "distances"], + query_embeddings=[embedding.tolist()], n_results=k, include=["documents", "distances"] ) ) distances = results["distances"][0] @@ -108,12 +94,7 @@ class ChromaIndex(EmbeddingIndex): async def delete(self): await maybe_await(self.client.delete_collection(self.collection.name)) - async def query_keyword( - self, - query_string: str, - k: int, - score_threshold: float, - ) -> QueryChunksResponse: + async def query_keyword(self, query_string: str, k: int, score_threshold: float) -> QueryChunksResponse: raise NotImplementedError("Keyword search is not supported in Chroma") async def delete_chunks(self, chunks_for_deletion: list[ChunkForDeletion]) -> None: @@ -133,26 +114,24 @@ class ChromaIndex(EmbeddingIndex): raise NotImplementedError("Hybrid search is not supported in Chroma") -class ChromaVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolPrivate): +class ChromaVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorStoresProtocolPrivate): def __init__( self, config: RemoteChromaVectorIOConfig | InlineChromaVectorIOConfig, - inference_api: Api.inference, - models_apis: Api.models, + inference_api: Inference, files_api: Files | None, ) -> None: super().__init__(files_api=files_api, kvstore=None) log.info(f"Initializing ChromaVectorIOAdapter with url: {config}") self.config = config self.inference_api = inference_api - self.models_api = models_apis self.client = None self.cache = {} - self.vector_db_store = None + self.vector_store_table = None async def initialize(self) -> None: - self.kvstore = await kvstore_impl(self.config.kvstore) - self.vector_db_store = self.kvstore + self.kvstore = await kvstore_impl(self.config.persistence) + self.vector_store_table = self.kvstore if isinstance(self.config, RemoteChromaVectorIOConfig): log.info(f"Connecting to Chroma server at: {self.config.url}") @@ -172,70 +151,58 @@ class ChromaVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolP # Clean up mixin resources (file batch tasks) await super().shutdown() - async def register_vector_db( - self, - vector_db: VectorDB, - ) -> None: + async def register_vector_store(self, vector_store: VectorStore) -> None: collection = await maybe_await( self.client.get_or_create_collection( - name=vector_db.identifier, - metadata={"vector_db": vector_db.model_dump_json()}, + name=vector_store.identifier, metadata={"vector_store": vector_store.model_dump_json()} ) ) - self.cache[vector_db.identifier] = VectorDBWithIndex( - vector_db, ChromaIndex(self.client, collection), self.inference_api + self.cache[vector_store.identifier] = VectorStoreWithIndex( + vector_store, ChromaIndex(self.client, collection), self.inference_api ) - async def unregister_vector_db(self, vector_db_id: str) -> None: - if vector_db_id not in self.cache: - log.warning(f"Vector DB {vector_db_id} not found") + async def unregister_vector_store(self, vector_store_id: str) -> None: + if vector_store_id not in self.cache: + log.warning(f"Vector DB {vector_store_id} not found") return - await self.cache[vector_db_id].index.delete() - del self.cache[vector_db_id] + await self.cache[vector_store_id].index.delete() + del self.cache[vector_store_id] - async def insert_chunks( - self, - vector_db_id: str, - chunks: list[Chunk], - ttl_seconds: int | None = None, - ) -> None: - index = await self._get_and_cache_vector_db_index(vector_db_id) + async def insert_chunks(self, vector_db_id: str, chunks: list[Chunk], ttl_seconds: int | None = None) -> None: + index = await self._get_and_cache_vector_store_index(vector_db_id) if index is None: raise ValueError(f"Vector DB {vector_db_id} not found in Chroma") await index.insert_chunks(chunks) async def query_chunks( - self, - vector_db_id: str, - query: InterleavedContent, - params: dict[str, Any] | None = None, + self, vector_db_id: str, query: InterleavedContent, params: dict[str, Any] | None = None ) -> QueryChunksResponse: - index = await self._get_and_cache_vector_db_index(vector_db_id) + index = await self._get_and_cache_vector_store_index(vector_db_id) if index is None: raise ValueError(f"Vector DB {vector_db_id} not found in Chroma") return await index.query_chunks(query, params) - async def _get_and_cache_vector_db_index(self, vector_db_id: str) -> VectorDBWithIndex: - if vector_db_id in self.cache: - return self.cache[vector_db_id] + async def _get_and_cache_vector_store_index(self, vector_store_id: str) -> VectorStoreWithIndex: + if vector_store_id in self.cache: + return self.cache[vector_store_id] - vector_db = await self.vector_db_store.get_vector_db(vector_db_id) - if not vector_db: - raise ValueError(f"Vector DB {vector_db_id} not found in Llama Stack") - collection = await maybe_await(self.client.get_collection(vector_db_id)) + vector_store = await self.vector_store_table.get_vector_store(vector_store_id) + if not vector_store: + raise ValueError(f"Vector DB {vector_store_id} not found in Llama Stack") + collection = await maybe_await(self.client.get_collection(vector_store_id)) if not collection: - raise ValueError(f"Vector DB {vector_db_id} not found in Chroma") - index = VectorDBWithIndex(vector_db, ChromaIndex(self.client, collection), self.inference_api) - self.cache[vector_db_id] = index + raise ValueError(f"Vector DB {vector_store_id} not found in Chroma") + index = VectorStoreWithIndex(vector_store, ChromaIndex(self.client, collection), self.inference_api) + self.cache[vector_store_id] = index return index async def delete_chunks(self, store_id: str, chunks_for_deletion: list[ChunkForDeletion]) -> None: """Delete chunks from a Chroma vector store.""" - index = await self._get_and_cache_vector_db_index(store_id) + index = await self._get_and_cache_vector_store_index(store_id) if not index: raise ValueError(f"Vector DB {store_id} not found") diff --git a/llama_stack/providers/remote/vector_io/chroma/config.py b/llama_stack/providers/remote/vector_io/chroma/config.py index a1193905a..209ba90bb 100644 --- a/llama_stack/providers/remote/vector_io/chroma/config.py +++ b/llama_stack/providers/remote/vector_io/chroma/config.py @@ -8,21 +8,21 @@ from typing import Any from pydantic import BaseModel, Field -from llama_stack.providers.utils.kvstore.config import KVStoreConfig, SqliteKVStoreConfig +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.schema_utils import json_schema_type @json_schema_type class ChromaVectorIOConfig(BaseModel): url: str | None - kvstore: KVStoreConfig = Field(description="Config for KV store backend") + persistence: KVStoreReference = Field(description="Config for KV store backend") @classmethod def sample_run_config(cls, __distro_dir__: str, url: str = "${env.CHROMADB_URL}", **kwargs: Any) -> dict[str, Any]: return { "url": url, - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="chroma_remote_registry.db", - ), + "persistence": KVStoreReference( + backend="kv_default", + namespace="vector_io::chroma_remote", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/remote/vector_io/milvus/__init__.py b/llama_stack/providers/remote/vector_io/milvus/__init__.py index dc5a642d6..526075bb2 100644 --- a/llama_stack/providers/remote/vector_io/milvus/__init__.py +++ b/llama_stack/providers/remote/vector_io/milvus/__init__.py @@ -13,12 +13,6 @@ async def get_adapter_impl(config: MilvusVectorIOConfig, deps: dict[Api, Provide from .milvus import MilvusVectorIOAdapter assert isinstance(config, MilvusVectorIOConfig), f"Unexpected config type: {type(config)}" - - impl = MilvusVectorIOAdapter( - config, - deps[Api.inference], - deps[Api.models], - deps.get(Api.files), - ) + impl = MilvusVectorIOAdapter(config, deps[Api.inference], deps.get(Api.files)) await impl.initialize() return impl diff --git a/llama_stack/providers/remote/vector_io/milvus/config.py b/llama_stack/providers/remote/vector_io/milvus/config.py index 899d3678d..8ff9e1328 100644 --- a/llama_stack/providers/remote/vector_io/milvus/config.py +++ b/llama_stack/providers/remote/vector_io/milvus/config.py @@ -8,7 +8,7 @@ from typing import Any from pydantic import BaseModel, ConfigDict, Field -from llama_stack.providers.utils.kvstore.config import KVStoreConfig, SqliteKVStoreConfig +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.schema_utils import json_schema_type @@ -17,7 +17,7 @@ class MilvusVectorIOConfig(BaseModel): uri: str = Field(description="The URI of the Milvus server") token: str | None = Field(description="The token of the Milvus server") consistency_level: str = Field(description="The consistency level of the Milvus server", default="Strong") - kvstore: KVStoreConfig = Field(description="Config for KV store backend") + persistence: KVStoreReference = Field(description="Config for KV store backend") # This configuration allows additional fields to be passed through to the underlying Milvus client. # See the [Milvus](https://milvus.io/docs/install-overview.md) documentation for more details about Milvus in general. @@ -28,8 +28,8 @@ class MilvusVectorIOConfig(BaseModel): return { "uri": "${env.MILVUS_ENDPOINT}", "token": "${env.MILVUS_TOKEN}", - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="milvus_remote_registry.db", - ), + "persistence": KVStoreReference( + backend="kv_default", + namespace="vector_io::milvus_remote", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/remote/vector_io/milvus/milvus.py b/llama_stack/providers/remote/vector_io/milvus/milvus.py index d7147a7f0..cccf13816 100644 --- a/llama_stack/providers/remote/vector_io/milvus/milvus.py +++ b/llama_stack/providers/remote/vector_io/milvus/milvus.py @@ -14,15 +14,10 @@ from pymilvus import AnnSearchRequest, DataType, Function, FunctionType, MilvusC from llama_stack.apis.common.errors import VectorStoreNotFoundError from llama_stack.apis.files import Files from llama_stack.apis.inference import Inference, InterleavedContent -from llama_stack.apis.models import Models -from llama_stack.apis.vector_dbs import VectorDB -from llama_stack.apis.vector_io import ( - Chunk, - QueryChunksResponse, - VectorIO, -) +from llama_stack.apis.vector_io import Chunk, QueryChunksResponse, VectorIO +from llama_stack.apis.vector_stores import VectorStore from llama_stack.log import get_logger -from llama_stack.providers.datatypes import VectorDBsProtocolPrivate +from llama_stack.providers.datatypes import VectorStoresProtocolPrivate from llama_stack.providers.inline.vector_io.milvus import MilvusVectorIOConfig as InlineMilvusVectorIOConfig from llama_stack.providers.utils.kvstore import kvstore_impl from llama_stack.providers.utils.kvstore.api import KVStore @@ -31,7 +26,7 @@ from llama_stack.providers.utils.memory.vector_store import ( RERANKER_TYPE_WEIGHTED, ChunkForDeletion, EmbeddingIndex, - VectorDBWithIndex, + VectorStoreWithIndex, ) from llama_stack.providers.utils.vector_io.vector_utils import sanitize_collection_name @@ -40,7 +35,7 @@ from .config import MilvusVectorIOConfig as RemoteMilvusVectorIOConfig logger = get_logger(name=__name__, category="vector_io::milvus") VERSION = "v3" -VECTOR_DBS_PREFIX = f"vector_dbs:milvus:{VERSION}::" +VECTOR_DBS_PREFIX = f"vector_stores:milvus:{VERSION}::" VECTOR_INDEX_PREFIX = f"vector_index:milvus:{VERSION}::" OPENAI_VECTOR_STORES_PREFIX = f"openai_vector_stores:milvus:{VERSION}::" OPENAI_VECTOR_STORES_FILES_PREFIX = f"openai_vector_stores_files:milvus:{VERSION}::" @@ -74,46 +69,23 @@ class MilvusIndex(EmbeddingIndex): logger.info(f"Creating new collection {self.collection_name} with nullable sparse field") # Create schema for vector search schema = self.client.create_schema() - schema.add_field( - field_name="chunk_id", - datatype=DataType.VARCHAR, - is_primary=True, - max_length=100, - ) + schema.add_field(field_name="chunk_id", datatype=DataType.VARCHAR, is_primary=True, max_length=100) schema.add_field( field_name="content", datatype=DataType.VARCHAR, max_length=65535, enable_analyzer=True, # Enable text analysis for BM25 ) - schema.add_field( - field_name="vector", - datatype=DataType.FLOAT_VECTOR, - dim=len(embeddings[0]), - ) - schema.add_field( - field_name="chunk_content", - datatype=DataType.JSON, - ) + schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=len(embeddings[0])) + schema.add_field(field_name="chunk_content", datatype=DataType.JSON) # Add sparse vector field for BM25 (required by the function) - schema.add_field( - field_name="sparse", - datatype=DataType.SPARSE_FLOAT_VECTOR, - ) + schema.add_field(field_name="sparse", datatype=DataType.SPARSE_FLOAT_VECTOR) # Create indexes index_params = self.client.prepare_index_params() - index_params.add_index( - field_name="vector", - index_type="FLAT", - metric_type="COSINE", - ) + index_params.add_index(field_name="vector", index_type="FLAT", metric_type="COSINE") # Add index for sparse field (required by BM25 function) - index_params.add_index( - field_name="sparse", - index_type="SPARSE_INVERTED_INDEX", - metric_type="BM25", - ) + index_params.add_index(field_name="sparse", index_type="SPARSE_INVERTED_INDEX", metric_type="BM25") # Add BM25 function for full-text search bm25_function = Function( @@ -144,11 +116,7 @@ class MilvusIndex(EmbeddingIndex): } ) try: - await asyncio.to_thread( - self.client.insert, - self.collection_name, - data=data, - ) + await asyncio.to_thread(self.client.insert, self.collection_name, data=data) except Exception as e: logger.error(f"Error inserting chunks into Milvus collection {self.collection_name}: {e}") raise e @@ -167,12 +135,7 @@ class MilvusIndex(EmbeddingIndex): scores = [res["distance"] for res in search_res[0]] return QueryChunksResponse(chunks=chunks, scores=scores) - async def query_keyword( - self, - query_string: str, - k: int, - score_threshold: float, - ) -> QueryChunksResponse: + async def query_keyword(self, query_string: str, k: int, score_threshold: float) -> QueryChunksResponse: """ Perform BM25-based keyword search using Milvus's built-in full-text search. """ @@ -210,12 +173,7 @@ class MilvusIndex(EmbeddingIndex): # Fallback to simple text search return await self._fallback_keyword_search(query_string, k, score_threshold) - async def _fallback_keyword_search( - self, - query_string: str, - k: int, - score_threshold: float, - ) -> QueryChunksResponse: + async def _fallback_keyword_search(self, query_string: str, k: int, score_threshold: float) -> QueryChunksResponse: """ Fallback to simple text search when BM25 search is not available. """ @@ -303,12 +261,11 @@ class MilvusIndex(EmbeddingIndex): raise -class MilvusVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolPrivate): +class MilvusVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorStoresProtocolPrivate): def __init__( self, config: RemoteMilvusVectorIOConfig | InlineMilvusVectorIOConfig, inference_api: Inference, - models_api: Models, files_api: Files | None, ) -> None: super().__init__(files_api=files_api, kvstore=None) @@ -316,29 +273,28 @@ class MilvusVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolP self.cache = {} self.client = None self.inference_api = inference_api - self.models_api = models_api - self.vector_db_store = None + self.vector_store_table = None self.metadata_collection_name = "openai_vector_stores_metadata" async def initialize(self) -> None: - self.kvstore = await kvstore_impl(self.config.kvstore) + self.kvstore = await kvstore_impl(self.config.persistence) start_key = VECTOR_DBS_PREFIX end_key = f"{VECTOR_DBS_PREFIX}\xff" - stored_vector_dbs = await self.kvstore.values_in_range(start_key, end_key) + stored_vector_stores = await self.kvstore.values_in_range(start_key, end_key) - for vector_db_data in stored_vector_dbs: - vector_db = VectorDB.model_validate_json(vector_db_data) - index = VectorDBWithIndex( - vector_db, + for vector_store_data in stored_vector_stores: + vector_store = VectorStore.model_validate_json(vector_store_data) + index = VectorStoreWithIndex( + vector_store, index=MilvusIndex( client=self.client, - collection_name=vector_db.identifier, + collection_name=vector_store.identifier, consistency_level=self.config.consistency_level, kvstore=self.kvstore, ), inference_api=self.inference_api, ) - self.cache[vector_db.identifier] = index + self.cache[vector_store.identifier] = index if isinstance(self.config, RemoteMilvusVectorIOConfig): logger.info(f"Connecting to Milvus server at {self.config.uri}") self.client = MilvusClient(**self.config.model_dump(exclude_none=True)) @@ -355,72 +311,61 @@ class MilvusVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolP # Clean up mixin resources (file batch tasks) await super().shutdown() - async def register_vector_db( - self, - vector_db: VectorDB, - ) -> None: + async def register_vector_store(self, vector_store: VectorStore) -> None: if isinstance(self.config, RemoteMilvusVectorIOConfig): consistency_level = self.config.consistency_level else: consistency_level = "Strong" - index = VectorDBWithIndex( - vector_db=vector_db, - index=MilvusIndex(self.client, vector_db.identifier, consistency_level=consistency_level), + index = VectorStoreWithIndex( + vector_store=vector_store, + index=MilvusIndex(self.client, vector_store.identifier, consistency_level=consistency_level), inference_api=self.inference_api, ) - self.cache[vector_db.identifier] = index + self.cache[vector_store.identifier] = index - async def _get_and_cache_vector_db_index(self, vector_db_id: str) -> VectorDBWithIndex | None: - if vector_db_id in self.cache: - return self.cache[vector_db_id] + async def _get_and_cache_vector_store_index(self, vector_store_id: str) -> VectorStoreWithIndex | None: + if vector_store_id in self.cache: + return self.cache[vector_store_id] - if self.vector_db_store is None: - raise VectorStoreNotFoundError(vector_db_id) + if self.vector_store_table is None: + raise VectorStoreNotFoundError(vector_store_id) - vector_db = await self.vector_db_store.get_vector_db(vector_db_id) - if not vector_db: - raise VectorStoreNotFoundError(vector_db_id) + vector_store = await self.vector_store_table.get_vector_store(vector_store_id) + if not vector_store: + raise VectorStoreNotFoundError(vector_store_id) - index = VectorDBWithIndex( - vector_db=vector_db, - index=MilvusIndex(client=self.client, collection_name=vector_db.identifier, kvstore=self.kvstore), + index = VectorStoreWithIndex( + vector_store=vector_store, + index=MilvusIndex(client=self.client, collection_name=vector_store.identifier, kvstore=self.kvstore), inference_api=self.inference_api, ) - self.cache[vector_db_id] = index + self.cache[vector_store_id] = index return index - async def unregister_vector_db(self, vector_db_id: str) -> None: - if vector_db_id in self.cache: - await self.cache[vector_db_id].index.delete() - del self.cache[vector_db_id] + async def unregister_vector_store(self, vector_store_id: str) -> None: + if vector_store_id in self.cache: + await self.cache[vector_store_id].index.delete() + del self.cache[vector_store_id] - async def insert_chunks( - self, - vector_db_id: str, - chunks: list[Chunk], - ttl_seconds: int | None = None, - ) -> None: - index = await self._get_and_cache_vector_db_index(vector_db_id) + async def insert_chunks(self, vector_db_id: str, chunks: list[Chunk], ttl_seconds: int | None = None) -> None: + index = await self._get_and_cache_vector_store_index(vector_db_id) if not index: raise VectorStoreNotFoundError(vector_db_id) await index.insert_chunks(chunks) async def query_chunks( - self, - vector_db_id: str, - query: InterleavedContent, - params: dict[str, Any] | None = None, + self, vector_db_id: str, query: InterleavedContent, params: dict[str, Any] | None = None ) -> QueryChunksResponse: - index = await self._get_and_cache_vector_db_index(vector_db_id) + index = await self._get_and_cache_vector_store_index(vector_db_id) if not index: raise VectorStoreNotFoundError(vector_db_id) return await index.query_chunks(query, params) async def delete_chunks(self, store_id: str, chunks_for_deletion: list[ChunkForDeletion]) -> None: """Delete a chunk from a milvus vector store.""" - index = await self._get_and_cache_vector_db_index(store_id) + index = await self._get_and_cache_vector_store_index(store_id) if not index: raise VectorStoreNotFoundError(store_id) diff --git a/llama_stack/providers/remote/vector_io/pgvector/__init__.py b/llama_stack/providers/remote/vector_io/pgvector/__init__.py index bb4079ab5..8086b7650 100644 --- a/llama_stack/providers/remote/vector_io/pgvector/__init__.py +++ b/llama_stack/providers/remote/vector_io/pgvector/__init__.py @@ -12,6 +12,6 @@ from .config import PGVectorVectorIOConfig async def get_adapter_impl(config: PGVectorVectorIOConfig, deps: dict[Api, ProviderSpec]): from .pgvector import PGVectorVectorIOAdapter - impl = PGVectorVectorIOAdapter(config, deps[Api.inference], deps[Api.models], deps.get(Api.files, None)) + impl = PGVectorVectorIOAdapter(config, deps[Api.inference], deps.get(Api.files)) await impl.initialize() return impl diff --git a/llama_stack/providers/remote/vector_io/pgvector/config.py b/llama_stack/providers/remote/vector_io/pgvector/config.py index 334cbe5be..d81e524e4 100644 --- a/llama_stack/providers/remote/vector_io/pgvector/config.py +++ b/llama_stack/providers/remote/vector_io/pgvector/config.py @@ -8,10 +8,7 @@ from typing import Any from pydantic import BaseModel, Field -from llama_stack.providers.utils.kvstore.config import ( - KVStoreConfig, - SqliteKVStoreConfig, -) +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.schema_utils import json_schema_type @@ -22,7 +19,9 @@ class PGVectorVectorIOConfig(BaseModel): db: str | None = Field(default="postgres") user: str | None = Field(default="postgres") password: str | None = Field(default="mysecretpassword") - kvstore: KVStoreConfig | None = Field(description="Config for KV store backend (SQLite only for now)", default=None) + persistence: KVStoreReference | None = Field( + description="Config for KV store backend (SQLite only for now)", default=None + ) @classmethod def sample_run_config( @@ -41,8 +40,8 @@ class PGVectorVectorIOConfig(BaseModel): "db": db, "user": user, "password": password, - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="pgvector_registry.db", - ), + "persistence": KVStoreReference( + backend="kv_default", + namespace="vector_io::pgvector", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/remote/vector_io/pgvector/pgvector.py b/llama_stack/providers/remote/vector_io/pgvector/pgvector.py index d55c13103..f28bd3cd9 100644 --- a/llama_stack/providers/remote/vector_io/pgvector/pgvector.py +++ b/llama_stack/providers/remote/vector_io/pgvector/pgvector.py @@ -16,26 +16,15 @@ from pydantic import BaseModel, TypeAdapter from llama_stack.apis.common.errors import VectorStoreNotFoundError from llama_stack.apis.files import Files from llama_stack.apis.inference import Inference, InterleavedContent -from llama_stack.apis.models import Models -from llama_stack.apis.vector_dbs import VectorDB -from llama_stack.apis.vector_io import ( - Chunk, - QueryChunksResponse, - VectorIO, -) +from llama_stack.apis.vector_io import Chunk, QueryChunksResponse, VectorIO +from llama_stack.apis.vector_stores import VectorStore from llama_stack.log import get_logger -from llama_stack.providers.datatypes import VectorDBsProtocolPrivate -from llama_stack.providers.utils.inference.prompt_adapter import ( - interleaved_content_as_str, -) +from llama_stack.providers.datatypes import VectorStoresProtocolPrivate +from llama_stack.providers.utils.inference.prompt_adapter import interleaved_content_as_str from llama_stack.providers.utils.kvstore import kvstore_impl from llama_stack.providers.utils.kvstore.api import KVStore from llama_stack.providers.utils.memory.openai_vector_store_mixin import OpenAIVectorStoreMixin -from llama_stack.providers.utils.memory.vector_store import ( - ChunkForDeletion, - EmbeddingIndex, - VectorDBWithIndex, -) +from llama_stack.providers.utils.memory.vector_store import ChunkForDeletion, EmbeddingIndex, VectorStoreWithIndex from llama_stack.providers.utils.vector_io.vector_utils import WeightedInMemoryAggregator, sanitize_collection_name from .config import PGVectorVectorIOConfig @@ -43,7 +32,7 @@ from .config import PGVectorVectorIOConfig log = get_logger(name=__name__, category="vector_io::pgvector") VERSION = "v3" -VECTOR_DBS_PREFIX = f"vector_dbs:pgvector:{VERSION}::" +VECTOR_DBS_PREFIX = f"vector_stores:pgvector:{VERSION}::" VECTOR_INDEX_PREFIX = f"vector_index:pgvector:{VERSION}::" OPENAI_VECTOR_STORES_PREFIX = f"openai_vector_stores:pgvector:{VERSION}::" OPENAI_VECTOR_STORES_FILES_PREFIX = f"openai_vector_stores_files:pgvector:{VERSION}::" @@ -90,13 +79,13 @@ class PGVectorIndex(EmbeddingIndex): def __init__( self, - vector_db: VectorDB, + vector_store: VectorStore, dimension: int, conn: psycopg2.extensions.connection, kvstore: KVStore | None = None, distance_metric: str = "COSINE", ): - self.vector_db = vector_db + self.vector_store = vector_store self.dimension = dimension self.conn = conn self.kvstore = kvstore @@ -108,9 +97,9 @@ class PGVectorIndex(EmbeddingIndex): try: with self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur: # Sanitize the table name by replacing hyphens with underscores - # SQL doesn't allow hyphens in table names, and vector_db.identifier may contain hyphens + # SQL doesn't allow hyphens in table names, and vector_store.identifier may contain hyphens # when created with patterns like "test-vector-db-{uuid4()}" - sanitized_identifier = sanitize_collection_name(self.vector_db.identifier) + sanitized_identifier = sanitize_collection_name(self.vector_store.identifier) self.table_name = f"vs_{sanitized_identifier}" cur.execute( @@ -133,8 +122,8 @@ class PGVectorIndex(EmbeddingIndex): """ ) except Exception as e: - log.exception(f"Error creating PGVectorIndex for vector_db: {self.vector_db.identifier}") - raise RuntimeError(f"Error creating PGVectorIndex for vector_db: {self.vector_db.identifier}") from e + log.exception(f"Error creating PGVectorIndex for vector_store: {self.vector_store.identifier}") + raise RuntimeError(f"Error creating PGVectorIndex for vector_store: {self.vector_store.identifier}") from e async def add_chunks(self, chunks: list[Chunk], embeddings: NDArray): assert len(chunks) == len(embeddings), ( @@ -205,12 +194,7 @@ class PGVectorIndex(EmbeddingIndex): return QueryChunksResponse(chunks=chunks, scores=scores) - async def query_keyword( - self, - query_string: str, - k: int, - score_threshold: float, - ) -> QueryChunksResponse: + async def query_keyword(self, query_string: str, k: int, score_threshold: float) -> QueryChunksResponse: """ Performs keyword-based search using PostgreSQL's full-text search with ts_rank scoring. @@ -317,7 +301,7 @@ class PGVectorIndex(EmbeddingIndex): """Remove a chunk from the PostgreSQL table.""" chunk_ids = [c.chunk_id for c in chunks_for_deletion] with self.conn.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur: - cur.execute(f"DELETE FROM {self.table_name} WHERE id = ANY(%s)", (chunk_ids,)) + cur.execute(f"DELETE FROM {self.table_name} WHERE id = ANY(%s)", (chunk_ids)) def get_pgvector_search_function(self) -> str: return self.PGVECTOR_DISTANCE_METRIC_TO_SEARCH_FUNCTION[self.distance_metric] @@ -339,26 +323,21 @@ class PGVectorIndex(EmbeddingIndex): ) -class PGVectorVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolPrivate): +class PGVectorVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorStoresProtocolPrivate): def __init__( - self, - config: PGVectorVectorIOConfig, - inference_api: Inference, - models_api: Models, - files_api: Files | None = None, + self, config: PGVectorVectorIOConfig, inference_api: Inference, files_api: Files | None = None ) -> None: super().__init__(files_api=files_api, kvstore=None) self.config = config self.inference_api = inference_api - self.models_api = models_api self.conn = None self.cache = {} - self.vector_db_store = None + self.vector_store_table = None self.metadata_collection_name = "openai_vector_stores_metadata" async def initialize(self) -> None: log.info(f"Initializing PGVector memory adapter with config: {self.config}") - self.kvstore = await kvstore_impl(self.config.kvstore) + self.kvstore = await kvstore_impl(self.config.persistence) await self.initialize_openai_vector_stores() try: @@ -396,71 +375,59 @@ class PGVectorVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtoco # Clean up mixin resources (file batch tasks) await super().shutdown() - async def register_vector_db(self, vector_db: VectorDB) -> None: + async def register_vector_store(self, vector_store: VectorStore) -> None: # Persist vector DB metadata in the KV store assert self.kvstore is not None # Upsert model metadata in Postgres - upsert_models(self.conn, [(vector_db.identifier, vector_db)]) + upsert_models(self.conn, [(vector_store.identifier, vector_store)]) # Create and cache the PGVector index table for the vector DB pgvector_index = PGVectorIndex( - vector_db=vector_db, dimension=vector_db.embedding_dimension, conn=self.conn, kvstore=self.kvstore + vector_store=vector_store, dimension=vector_store.embedding_dimension, conn=self.conn, kvstore=self.kvstore ) await pgvector_index.initialize() - index = VectorDBWithIndex( - vector_db, - index=pgvector_index, - inference_api=self.inference_api, - ) - self.cache[vector_db.identifier] = index + index = VectorStoreWithIndex(vector_store, index=pgvector_index, inference_api=self.inference_api) + self.cache[vector_store.identifier] = index - async def unregister_vector_db(self, vector_db_id: str) -> None: + async def unregister_vector_store(self, vector_store_id: str) -> None: # Remove provider index and cache - if vector_db_id in self.cache: - await self.cache[vector_db_id].index.delete() - del self.cache[vector_db_id] + if vector_store_id in self.cache: + await self.cache[vector_store_id].index.delete() + del self.cache[vector_store_id] # Delete vector DB metadata from KV store assert self.kvstore is not None - await self.kvstore.delete(key=f"{VECTOR_DBS_PREFIX}{vector_db_id}") + await self.kvstore.delete(key=f"{VECTOR_DBS_PREFIX}{vector_store_id}") - async def insert_chunks( - self, - vector_db_id: str, - chunks: list[Chunk], - ttl_seconds: int | None = None, - ) -> None: - index = await self._get_and_cache_vector_db_index(vector_db_id) + async def insert_chunks(self, vector_db_id: str, chunks: list[Chunk], ttl_seconds: int | None = None) -> None: + index = await self._get_and_cache_vector_store_index(vector_db_id) await index.insert_chunks(chunks) async def query_chunks( - self, - vector_db_id: str, - query: InterleavedContent, - params: dict[str, Any] | None = None, + self, vector_db_id: str, query: InterleavedContent, params: dict[str, Any] | None = None ) -> QueryChunksResponse: - index = await self._get_and_cache_vector_db_index(vector_db_id) + index = await self._get_and_cache_vector_store_index(vector_db_id) return await index.query_chunks(query, params) - async def _get_and_cache_vector_db_index(self, vector_db_id: str) -> VectorDBWithIndex: - if vector_db_id in self.cache: - return self.cache[vector_db_id] + async def _get_and_cache_vector_store_index(self, vector_store_id: str) -> VectorStoreWithIndex: + if vector_store_id in self.cache: + return self.cache[vector_store_id] - if self.vector_db_store is None: - raise VectorStoreNotFoundError(vector_db_id) + if self.vector_store_table is None: + raise VectorStoreNotFoundError(vector_store_id) - vector_db = await self.vector_db_store.get_vector_db(vector_db_id) - if not vector_db: - raise VectorStoreNotFoundError(vector_db_id) + vector_store = await self.vector_store_table.get_vector_store(vector_store_id) + if not vector_store: + raise VectorStoreNotFoundError(vector_store_id) - index = PGVectorIndex(vector_db, vector_db.embedding_dimension, self.conn) + index = PGVectorIndex(vector_store, vector_store.embedding_dimension, self.conn) await index.initialize() - self.cache[vector_db_id] = VectorDBWithIndex(vector_db, index, self.inference_api) - return self.cache[vector_db_id] + self.cache[vector_store_id] = VectorStoreWithIndex(vector_store, index, self.inference_api) + return self.cache[vector_store_id] async def delete_chunks(self, store_id: str, chunks_for_deletion: list[ChunkForDeletion]) -> None: """Delete a chunk from a PostgreSQL vector store.""" - index = await self._get_and_cache_vector_db_index(store_id) + index = await self._get_and_cache_vector_store_index(store_id) if not index: raise VectorStoreNotFoundError(store_id) diff --git a/llama_stack/providers/remote/vector_io/qdrant/__init__.py b/llama_stack/providers/remote/vector_io/qdrant/__init__.py index c4942fbce..e9527f101 100644 --- a/llama_stack/providers/remote/vector_io/qdrant/__init__.py +++ b/llama_stack/providers/remote/vector_io/qdrant/__init__.py @@ -12,11 +12,6 @@ from .config import QdrantVectorIOConfig async def get_adapter_impl(config: QdrantVectorIOConfig, deps: dict[Api, ProviderSpec]): from .qdrant import QdrantVectorIOAdapter - impl = QdrantVectorIOAdapter( - config, - deps[Api.inference], - deps[Api.models], - deps.get(Api.files), - ) + impl = QdrantVectorIOAdapter(config, deps[Api.inference], deps.get(Api.files)) await impl.initialize() return impl diff --git a/llama_stack/providers/remote/vector_io/qdrant/config.py b/llama_stack/providers/remote/vector_io/qdrant/config.py index ff5506236..01fbcc5cb 100644 --- a/llama_stack/providers/remote/vector_io/qdrant/config.py +++ b/llama_stack/providers/remote/vector_io/qdrant/config.py @@ -8,10 +8,7 @@ from typing import Any from pydantic import BaseModel -from llama_stack.providers.utils.kvstore.config import ( - KVStoreConfig, - SqliteKVStoreConfig, -) +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.schema_utils import json_schema_type @@ -27,14 +24,14 @@ class QdrantVectorIOConfig(BaseModel): prefix: str | None = None timeout: int | None = None host: str | None = None - kvstore: KVStoreConfig + persistence: KVStoreReference @classmethod def sample_run_config(cls, __distro_dir__: str, **kwargs: Any) -> dict[str, Any]: return { "api_key": "${env.QDRANT_API_KEY:=}", - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="qdrant_registry.db", - ), + "persistence": KVStoreReference( + backend="kv_default", + namespace="vector_io::qdrant_remote", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/remote/vector_io/qdrant/qdrant.py b/llama_stack/providers/remote/vector_io/qdrant/qdrant.py index 8b90935cd..93d0894a6 100644 --- a/llama_stack/providers/remote/vector_io/qdrant/qdrant.py +++ b/llama_stack/providers/remote/vector_io/qdrant/qdrant.py @@ -16,8 +16,6 @@ from qdrant_client.models import PointStruct from llama_stack.apis.common.errors import VectorStoreNotFoundError from llama_stack.apis.files import Files from llama_stack.apis.inference import Inference, InterleavedContent -from llama_stack.apis.models import Models -from llama_stack.apis.vector_dbs import VectorDB from llama_stack.apis.vector_io import ( Chunk, QueryChunksResponse, @@ -25,16 +23,13 @@ from llama_stack.apis.vector_io import ( VectorStoreChunkingStrategy, VectorStoreFileObject, ) +from llama_stack.apis.vector_stores import VectorStore from llama_stack.log import get_logger -from llama_stack.providers.datatypes import VectorDBsProtocolPrivate +from llama_stack.providers.datatypes import VectorStoresProtocolPrivate from llama_stack.providers.inline.vector_io.qdrant import QdrantVectorIOConfig as InlineQdrantVectorIOConfig from llama_stack.providers.utils.kvstore import kvstore_impl from llama_stack.providers.utils.memory.openai_vector_store_mixin import OpenAIVectorStoreMixin -from llama_stack.providers.utils.memory.vector_store import ( - ChunkForDeletion, - EmbeddingIndex, - VectorDBWithIndex, -) +from llama_stack.providers.utils.memory.vector_store import ChunkForDeletion, EmbeddingIndex, VectorStoreWithIndex from .config import QdrantVectorIOConfig as RemoteQdrantVectorIOConfig @@ -43,7 +38,7 @@ CHUNK_ID_KEY = "_chunk_id" # KV store prefixes for vector databases VERSION = "v3" -VECTOR_DBS_PREFIX = f"vector_dbs:qdrant:{VERSION}::" +VECTOR_DBS_PREFIX = f"vector_stores:qdrant:{VERSION}::" def convert_id(_id: str) -> str: @@ -99,8 +94,7 @@ class QdrantIndex(EmbeddingIndex): chunk_ids = [convert_id(c.chunk_id) for c in chunks_for_deletion] try: await self.client.delete( - collection_name=self.collection_name, - points_selector=models.PointIdsList(points=chunk_ids), + collection_name=self.collection_name, points_selector=models.PointIdsList(points=chunk_ids) ) except Exception as e: log.error(f"Error deleting chunks from Qdrant collection {self.collection_name}: {e}") @@ -133,12 +127,7 @@ class QdrantIndex(EmbeddingIndex): return QueryChunksResponse(chunks=chunks, scores=scores) - async def query_keyword( - self, - query_string: str, - k: int, - score_threshold: float, - ) -> QueryChunksResponse: + async def query_keyword(self, query_string: str, k: int, score_threshold: float) -> QueryChunksResponse: raise NotImplementedError("Keyword search is not supported in Qdrant") async def query_hybrid( @@ -156,12 +145,11 @@ class QdrantIndex(EmbeddingIndex): await self.client.delete_collection(collection_name=self.collection_name) -class QdrantVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolPrivate): +class QdrantVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorStoresProtocolPrivate): def __init__( self, config: RemoteQdrantVectorIOConfig | InlineQdrantVectorIOConfig, inference_api: Inference, - models_api: Models, files_api: Files | None = None, ) -> None: super().__init__(files_api=files_api, kvstore=None) @@ -169,27 +157,24 @@ class QdrantVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolP self.client: AsyncQdrantClient = None self.cache = {} self.inference_api = inference_api - self.models_api = models_api - self.vector_db_store = None + self.vector_store_table = None self._qdrant_lock = asyncio.Lock() async def initialize(self) -> None: - client_config = self.config.model_dump(exclude_none=True, exclude={"kvstore"}) + client_config = self.config.model_dump(exclude_none=True, exclude={"persistence"}) self.client = AsyncQdrantClient(**client_config) - self.kvstore = await kvstore_impl(self.config.kvstore) + self.kvstore = await kvstore_impl(self.config.persistence) start_key = VECTOR_DBS_PREFIX end_key = f"{VECTOR_DBS_PREFIX}\xff" - stored_vector_dbs = await self.kvstore.values_in_range(start_key, end_key) + stored_vector_stores = await self.kvstore.values_in_range(start_key, end_key) - for vector_db_data in stored_vector_dbs: - vector_db = VectorDB.model_validate_json(vector_db_data) - index = VectorDBWithIndex( - vector_db, - QdrantIndex(self.client, vector_db.identifier), - self.inference_api, + for vector_store_data in stored_vector_stores: + vector_store = VectorStore.model_validate_json(vector_store_data) + index = VectorStoreWithIndex( + vector_store, QdrantIndex(self.client, vector_store.identifier), self.inference_api ) - self.cache[vector_db.identifier] = index + self.cache[vector_store.identifier] = index self.openai_vector_stores = await self._load_openai_vector_stores() async def shutdown(self) -> None: @@ -197,68 +182,57 @@ class QdrantVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolP # Clean up mixin resources (file batch tasks) await super().shutdown() - async def register_vector_db( - self, - vector_db: VectorDB, - ) -> None: + async def register_vector_store(self, vector_store: VectorStore) -> None: assert self.kvstore is not None - key = f"{VECTOR_DBS_PREFIX}{vector_db.identifier}" - await self.kvstore.set(key=key, value=vector_db.model_dump_json()) + key = f"{VECTOR_DBS_PREFIX}{vector_store.identifier}" + await self.kvstore.set(key=key, value=vector_store.model_dump_json()) - index = VectorDBWithIndex( - vector_db=vector_db, - index=QdrantIndex(self.client, vector_db.identifier), + index = VectorStoreWithIndex( + vector_store=vector_store, + index=QdrantIndex(self.client, vector_store.identifier), inference_api=self.inference_api, ) - self.cache[vector_db.identifier] = index + self.cache[vector_store.identifier] = index - async def unregister_vector_db(self, vector_db_id: str) -> None: - if vector_db_id in self.cache: - await self.cache[vector_db_id].index.delete() - del self.cache[vector_db_id] + async def unregister_vector_store(self, vector_store_id: str) -> None: + if vector_store_id in self.cache: + await self.cache[vector_store_id].index.delete() + del self.cache[vector_store_id] assert self.kvstore is not None - await self.kvstore.delete(f"{VECTOR_DBS_PREFIX}{vector_db_id}") + await self.kvstore.delete(f"{VECTOR_DBS_PREFIX}{vector_store_id}") - async def _get_and_cache_vector_db_index(self, vector_db_id: str) -> VectorDBWithIndex | None: - if vector_db_id in self.cache: - return self.cache[vector_db_id] + async def _get_and_cache_vector_store_index(self, vector_store_id: str) -> VectorStoreWithIndex | None: + if vector_store_id in self.cache: + return self.cache[vector_store_id] - if self.vector_db_store is None: - raise ValueError(f"Vector DB not found {vector_db_id}") + if self.vector_store_table is None: + raise ValueError(f"Vector DB not found {vector_store_id}") - vector_db = await self.vector_db_store.get_vector_db(vector_db_id) - if not vector_db: - raise VectorStoreNotFoundError(vector_db_id) + vector_store = await self.vector_store_table.get_vector_store(vector_store_id) + if not vector_store: + raise VectorStoreNotFoundError(vector_store_id) - index = VectorDBWithIndex( - vector_db=vector_db, - index=QdrantIndex(client=self.client, collection_name=vector_db.identifier), + index = VectorStoreWithIndex( + vector_store=vector_store, + index=QdrantIndex(client=self.client, collection_name=vector_store.identifier), inference_api=self.inference_api, ) - self.cache[vector_db_id] = index + self.cache[vector_store_id] = index return index - async def insert_chunks( - self, - vector_db_id: str, - chunks: list[Chunk], - ttl_seconds: int | None = None, - ) -> None: - index = await self._get_and_cache_vector_db_index(vector_db_id) + async def insert_chunks(self, vector_db_id: str, chunks: list[Chunk], ttl_seconds: int | None = None) -> None: + index = await self._get_and_cache_vector_store_index(vector_db_id) if not index: raise VectorStoreNotFoundError(vector_db_id) await index.insert_chunks(chunks) async def query_chunks( - self, - vector_db_id: str, - query: InterleavedContent, - params: dict[str, Any] | None = None, + self, vector_db_id: str, query: InterleavedContent, params: dict[str, Any] | None = None ) -> QueryChunksResponse: - index = await self._get_and_cache_vector_db_index(vector_db_id) + index = await self._get_and_cache_vector_store_index(vector_db_id) if not index: raise VectorStoreNotFoundError(vector_db_id) @@ -279,7 +253,7 @@ class QdrantVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, VectorDBsProtocolP async def delete_chunks(self, store_id: str, chunks_for_deletion: list[ChunkForDeletion]) -> None: """Delete chunks from a Qdrant vector store.""" - index = await self._get_and_cache_vector_db_index(store_id) + index = await self._get_and_cache_vector_store_index(store_id) if not index: raise ValueError(f"Vector DB {store_id} not found") diff --git a/llama_stack/providers/remote/vector_io/weaviate/__init__.py b/llama_stack/providers/remote/vector_io/weaviate/__init__.py index 2040dad96..12e11d013 100644 --- a/llama_stack/providers/remote/vector_io/weaviate/__init__.py +++ b/llama_stack/providers/remote/vector_io/weaviate/__init__.py @@ -12,11 +12,6 @@ from .config import WeaviateVectorIOConfig async def get_adapter_impl(config: WeaviateVectorIOConfig, deps: dict[Api, ProviderSpec]): from .weaviate import WeaviateVectorIOAdapter - impl = WeaviateVectorIOAdapter( - config, - deps[Api.inference], - deps[Api.models], - deps.get(Api.files), - ) + impl = WeaviateVectorIOAdapter(config, deps[Api.inference], deps.get(Api.files)) await impl.initialize() return impl diff --git a/llama_stack/providers/remote/vector_io/weaviate/config.py b/llama_stack/providers/remote/vector_io/weaviate/config.py index b693e294e..66dbf1fed 100644 --- a/llama_stack/providers/remote/vector_io/weaviate/config.py +++ b/llama_stack/providers/remote/vector_io/weaviate/config.py @@ -8,10 +8,7 @@ from typing import Any from pydantic import BaseModel, Field -from llama_stack.providers.utils.kvstore.config import ( - KVStoreConfig, - SqliteKVStoreConfig, -) +from llama_stack.core.storage.datatypes import KVStoreReference from llama_stack.schema_utils import json_schema_type @@ -19,19 +16,17 @@ from llama_stack.schema_utils import json_schema_type class WeaviateVectorIOConfig(BaseModel): weaviate_api_key: str | None = Field(description="The API key for the Weaviate instance", default=None) weaviate_cluster_url: str | None = Field(description="The URL of the Weaviate cluster", default="localhost:8080") - kvstore: KVStoreConfig | None = Field(description="Config for KV store backend (SQLite only for now)", default=None) + persistence: KVStoreReference | None = Field( + description="Config for KV store backend (SQLite only for now)", default=None + ) @classmethod - def sample_run_config( - cls, - __distro_dir__: str, - **kwargs: Any, - ) -> dict[str, Any]: + def sample_run_config(cls, __distro_dir__: str, **kwargs: Any) -> dict[str, Any]: return { "weaviate_api_key": None, "weaviate_cluster_url": "${env.WEAVIATE_CLUSTER_URL:=localhost:8080}", - "kvstore": SqliteKVStoreConfig.sample_run_config( - __distro_dir__=__distro_dir__, - db_name="weaviate_registry.db", - ), + "persistence": KVStoreReference( + backend="kv_default", + namespace="vector_io::weaviate", + ).model_dump(exclude_none=True), } diff --git a/llama_stack/providers/remote/vector_io/weaviate/weaviate.py b/llama_stack/providers/remote/vector_io/weaviate/weaviate.py index d8b11c441..66922aa3f 100644 --- a/llama_stack/providers/remote/vector_io/weaviate/weaviate.py +++ b/llama_stack/providers/remote/vector_io/weaviate/weaviate.py @@ -16,22 +16,19 @@ from llama_stack.apis.common.content_types import InterleavedContent from llama_stack.apis.common.errors import VectorStoreNotFoundError from llama_stack.apis.files import Files from llama_stack.apis.inference import Inference -from llama_stack.apis.models import Models -from llama_stack.apis.vector_dbs import VectorDB from llama_stack.apis.vector_io import Chunk, QueryChunksResponse, VectorIO +from llama_stack.apis.vector_stores import VectorStore from llama_stack.core.request_headers import NeedsRequestProviderData from llama_stack.log import get_logger -from llama_stack.providers.datatypes import VectorDBsProtocolPrivate +from llama_stack.providers.datatypes import VectorStoresProtocolPrivate from llama_stack.providers.utils.kvstore import kvstore_impl from llama_stack.providers.utils.kvstore.api import KVStore -from llama_stack.providers.utils.memory.openai_vector_store_mixin import ( - OpenAIVectorStoreMixin, -) +from llama_stack.providers.utils.memory.openai_vector_store_mixin import OpenAIVectorStoreMixin from llama_stack.providers.utils.memory.vector_store import ( RERANKER_TYPE_RRF, ChunkForDeletion, EmbeddingIndex, - VectorDBWithIndex, + VectorStoreWithIndex, ) from llama_stack.providers.utils.vector_io.vector_utils import sanitize_collection_name @@ -40,7 +37,7 @@ from .config import WeaviateVectorIOConfig log = get_logger(name=__name__, category="vector_io::weaviate") VERSION = "v3" -VECTOR_DBS_PREFIX = f"vector_dbs:weaviate:{VERSION}::" +VECTOR_DBS_PREFIX = f"vector_stores:weaviate:{VERSION}::" VECTOR_INDEX_PREFIX = f"vector_index:weaviate:{VERSION}::" OPENAI_VECTOR_STORES_PREFIX = f"openai_vector_stores:weaviate:{VERSION}::" OPENAI_VECTOR_STORES_FILES_PREFIX = f"openai_vector_stores_files:weaviate:{VERSION}::" @@ -48,12 +45,7 @@ OPENAI_VECTOR_STORES_FILES_CONTENTS_PREFIX = f"openai_vector_stores_files_conten class WeaviateIndex(EmbeddingIndex): - def __init__( - self, - client: weaviate.WeaviateClient, - collection_name: str, - kvstore: KVStore | None = None, - ): + def __init__(self, client: weaviate.WeaviateClient, collection_name: str, kvstore: KVStore | None = None): self.client = client self.collection_name = sanitize_collection_name(collection_name, weaviate_format=True) self.kvstore = kvstore @@ -108,9 +100,7 @@ class WeaviateIndex(EmbeddingIndex): try: results = collection.query.near_vector( - near_vector=embedding.tolist(), - limit=k, - return_metadata=wvc.query.MetadataQuery(distance=True), + near_vector=embedding.tolist(), limit=k, return_metadata=wvc.query.MetadataQuery(distance=True) ) except Exception as e: log.error(f"Weaviate client vector search failed: {e}") @@ -153,12 +143,7 @@ class WeaviateIndex(EmbeddingIndex): collection = self.client.collections.get(sanitized_collection_name) collection.data.delete_many(where=Filter.by_property("id").contains_any(chunk_ids)) - async def query_keyword( - self, - query_string: str, - k: int, - score_threshold: float, - ) -> QueryChunksResponse: + async def query_keyword(self, query_string: str, k: int, score_threshold: float) -> QueryChunksResponse: """ Performs BM25-based keyword search using Weaviate's built-in full-text search. Args: @@ -175,9 +160,7 @@ class WeaviateIndex(EmbeddingIndex): # Perform BM25 keyword search on chunk_content field try: results = collection.query.bm25( - query=query_string, - limit=k, - return_metadata=wvc.query.MetadataQuery(score=True), + query=query_string, limit=k, return_metadata=wvc.query.MetadataQuery(score=True) ) except Exception as e: log.error(f"Weaviate client keyword search failed: {e}") @@ -274,26 +257,14 @@ class WeaviateIndex(EmbeddingIndex): return QueryChunksResponse(chunks=chunks, scores=scores) -class WeaviateVectorIOAdapter( - OpenAIVectorStoreMixin, - VectorIO, - NeedsRequestProviderData, - VectorDBsProtocolPrivate, -): - def __init__( - self, - config: WeaviateVectorIOConfig, - inference_api: Inference, - models_api: Models, - files_api: Files | None, - ) -> None: +class WeaviateVectorIOAdapter(OpenAIVectorStoreMixin, VectorIO, NeedsRequestProviderData, VectorStoresProtocolPrivate): + def __init__(self, config: WeaviateVectorIOConfig, inference_api: Inference, files_api: Files | None) -> None: super().__init__(files_api=files_api, kvstore=None) self.config = config self.inference_api = inference_api - self.models_api = models_api self.client_cache = {} self.cache = {} - self.vector_db_store = None + self.vector_store_table = None self.metadata_collection_name = "openai_vector_stores_metadata" def _get_client(self) -> weaviate.WeaviateClient: @@ -301,10 +272,7 @@ class WeaviateVectorIOAdapter( log.info("Using Weaviate locally in container") host, port = self.config.weaviate_cluster_url.split(":") key = "local_test" - client = weaviate.connect_to_local( - host=host, - port=port, - ) + client = weaviate.connect_to_local(host=host, port=port) else: log.info("Using Weaviate remote cluster with URL") key = f"{self.config.weaviate_cluster_url}::{self.config.weaviate_api_key}" @@ -320,8 +288,8 @@ class WeaviateVectorIOAdapter( async def initialize(self) -> None: """Set up KV store and load existing vector DBs and OpenAI vector stores.""" # Initialize KV store for metadata if configured - if self.config.kvstore is not None: - self.kvstore = await kvstore_impl(self.config.kvstore) + if self.config.persistence is not None: + self.kvstore = await kvstore_impl(self.config.persistence) else: self.kvstore = None log.info("No kvstore configured, registry will not persist across restarts") @@ -332,17 +300,11 @@ class WeaviateVectorIOAdapter( end_key = f"{VECTOR_DBS_PREFIX}\xff" stored = await self.kvstore.values_in_range(start_key, end_key) for raw in stored: - vector_db = VectorDB.model_validate_json(raw) + vector_store = VectorStore.model_validate_json(raw) client = self._get_client() - idx = WeaviateIndex( - client=client, - collection_name=vector_db.identifier, - kvstore=self.kvstore, - ) - self.cache[vector_db.identifier] = VectorDBWithIndex( - vector_db=vector_db, - index=idx, - inference_api=self.inference_api, + idx = WeaviateIndex(client=client, collection_name=vector_store.identifier, kvstore=self.kvstore) + self.cache[vector_store.identifier] = VectorStoreWithIndex( + vector_store=vector_store, index=idx, inference_api=self.inference_api ) # Load OpenAI vector stores metadata into cache @@ -354,90 +316,74 @@ class WeaviateVectorIOAdapter( # Clean up mixin resources (file batch tasks) await super().shutdown() - async def register_vector_db( - self, - vector_db: VectorDB, - ) -> None: + async def register_vector_store(self, vector_store: VectorStore) -> None: client = self._get_client() - sanitized_collection_name = sanitize_collection_name(vector_db.identifier, weaviate_format=True) + sanitized_collection_name = sanitize_collection_name(vector_store.identifier, weaviate_format=True) # Create collection if it doesn't exist if not client.collections.exists(sanitized_collection_name): client.collections.create( name=sanitized_collection_name, vectorizer_config=wvc.config.Configure.Vectorizer.none(), properties=[ - wvc.config.Property( - name="chunk_content", - data_type=wvc.config.DataType.TEXT, - ), + wvc.config.Property(name="chunk_content", data_type=wvc.config.DataType.TEXT), ], ) - self.cache[vector_db.identifier] = VectorDBWithIndex( - vector_db, - WeaviateIndex(client=client, collection_name=sanitized_collection_name), - self.inference_api, + self.cache[vector_store.identifier] = VectorStoreWithIndex( + vector_store, WeaviateIndex(client=client, collection_name=sanitized_collection_name), self.inference_api ) - async def unregister_vector_db(self, vector_db_id: str) -> None: + async def unregister_vector_store(self, vector_store_id: str) -> None: client = self._get_client() - sanitized_collection_name = sanitize_collection_name(vector_db_id, weaviate_format=True) - if vector_db_id not in self.cache or client.collections.exists(sanitized_collection_name) is False: + sanitized_collection_name = sanitize_collection_name(vector_store_id, weaviate_format=True) + if vector_store_id not in self.cache or client.collections.exists(sanitized_collection_name) is False: return client.collections.delete(sanitized_collection_name) - await self.cache[vector_db_id].index.delete() - del self.cache[vector_db_id] + await self.cache[vector_store_id].index.delete() + del self.cache[vector_store_id] - async def _get_and_cache_vector_db_index(self, vector_db_id: str) -> VectorDBWithIndex | None: - if vector_db_id in self.cache: - return self.cache[vector_db_id] + async def _get_and_cache_vector_store_index(self, vector_store_id: str) -> VectorStoreWithIndex | None: + if vector_store_id in self.cache: + return self.cache[vector_store_id] - if self.vector_db_store is None: - raise VectorStoreNotFoundError(vector_db_id) + if self.vector_store_table is None: + raise VectorStoreNotFoundError(vector_store_id) - vector_db = await self.vector_db_store.get_vector_db(vector_db_id) - if not vector_db: - raise VectorStoreNotFoundError(vector_db_id) + vector_store = await self.vector_store_table.get_vector_store(vector_store_id) + if not vector_store: + raise VectorStoreNotFoundError(vector_store_id) client = self._get_client() - sanitized_collection_name = sanitize_collection_name(vector_db.identifier, weaviate_format=True) + sanitized_collection_name = sanitize_collection_name(vector_store.identifier, weaviate_format=True) if not client.collections.exists(sanitized_collection_name): raise ValueError(f"Collection with name `{sanitized_collection_name}` not found") - index = VectorDBWithIndex( - vector_db=vector_db, - index=WeaviateIndex(client=client, collection_name=vector_db.identifier), + index = VectorStoreWithIndex( + vector_store=vector_store, + index=WeaviateIndex(client=client, collection_name=vector_store.identifier), inference_api=self.inference_api, ) - self.cache[vector_db_id] = index + self.cache[vector_store_id] = index return index - async def insert_chunks( - self, - vector_db_id: str, - chunks: list[Chunk], - ttl_seconds: int | None = None, - ) -> None: - index = await self._get_and_cache_vector_db_index(vector_db_id) + async def insert_chunks(self, vector_db_id: str, chunks: list[Chunk], ttl_seconds: int | None = None) -> None: + index = await self._get_and_cache_vector_store_index(vector_db_id) if not index: raise VectorStoreNotFoundError(vector_db_id) await index.insert_chunks(chunks) async def query_chunks( - self, - vector_db_id: str, - query: InterleavedContent, - params: dict[str, Any] | None = None, + self, vector_db_id: str, query: InterleavedContent, params: dict[str, Any] | None = None ) -> QueryChunksResponse: - index = await self._get_and_cache_vector_db_index(vector_db_id) + index = await self._get_and_cache_vector_store_index(vector_db_id) if not index: raise VectorStoreNotFoundError(vector_db_id) return await index.query_chunks(query, params) async def delete_chunks(self, store_id: str, chunks_for_deletion: list[ChunkForDeletion]) -> None: - index = await self._get_and_cache_vector_db_index(store_id) + index = await self._get_and_cache_vector_store_index(store_id) if not index: raise ValueError(f"Vector DB {store_id} not found") diff --git a/llama_stack/providers/utils/inference/embedding_mixin.py b/llama_stack/providers/utils/inference/embedding_mixin.py index 67ce8b532..c959b9c19 100644 --- a/llama_stack/providers/utils/inference/embedding_mixin.py +++ b/llama_stack/providers/utils/inference/embedding_mixin.py @@ -6,9 +6,12 @@ import asyncio import base64 +import platform import struct from typing import TYPE_CHECKING +import torch + from llama_stack.log import get_logger if TYPE_CHECKING: @@ -24,6 +27,8 @@ from llama_stack.apis.inference import ( EMBEDDING_MODELS = {} +DARWIN = "Darwin" + log = get_logger(name=__name__, category="providers::utils") @@ -83,6 +88,13 @@ class SentenceTransformerEmbeddingMixin: def _load_model(): from sentence_transformers import SentenceTransformer + platform_name = platform.system() + if platform_name == DARWIN: + # PyTorch's OpenMP kernels can segfault on macOS when spawned from background + # threads with the default parallel settings, so force a single-threaded CPU run. + log.debug(f"Constraining torch threads on {platform_name} to a single worker") + torch.set_num_threads(1) + return SentenceTransformer(model, trust_remote_code=True) loaded_model = await asyncio.to_thread(_load_model) diff --git a/llama_stack/providers/utils/inference/inference_store.py b/llama_stack/providers/utils/inference/inference_store.py index 901f77c67..8e20bca6b 100644 --- a/llama_stack/providers/utils/inference/inference_store.py +++ b/llama_stack/providers/utils/inference/inference_store.py @@ -15,12 +15,13 @@ from llama_stack.apis.inference import ( OpenAIMessageParam, Order, ) -from llama_stack.core.datatypes import AccessRule, InferenceStoreConfig +from llama_stack.core.datatypes import AccessRule +from llama_stack.core.storage.datatypes import InferenceStoreReference, StorageBackendType from llama_stack.log import get_logger from ..sqlstore.api import ColumnDefinition, ColumnType from ..sqlstore.authorized_sqlstore import AuthorizedSqlStore -from ..sqlstore.sqlstore import SqlStoreConfig, SqlStoreType, sqlstore_impl +from ..sqlstore.sqlstore import _SQLSTORE_BACKENDS, sqlstore_impl logger = get_logger(name=__name__, category="inference") @@ -28,33 +29,32 @@ logger = get_logger(name=__name__, category="inference") class InferenceStore: def __init__( self, - config: InferenceStoreConfig | SqlStoreConfig, + reference: InferenceStoreReference, policy: list[AccessRule], ): - # Handle backward compatibility - if not isinstance(config, InferenceStoreConfig): - # Legacy: SqlStoreConfig passed directly as config - config = InferenceStoreConfig( - sql_store_config=config, - ) - - self.config = config - self.sql_store_config = config.sql_store_config + self.reference = reference self.sql_store = None self.policy = policy - # Disable write queue for SQLite to avoid concurrency issues - self.enable_write_queue = self.sql_store_config.type != SqlStoreType.sqlite - # Async write queue and worker control self._queue: asyncio.Queue[tuple[OpenAIChatCompletion, list[OpenAIMessageParam]]] | None = None self._worker_tasks: list[asyncio.Task[Any]] = [] - self._max_write_queue_size: int = config.max_write_queue_size - self._num_writers: int = max(1, config.num_writers) + self._max_write_queue_size: int = reference.max_write_queue_size + self._num_writers: int = max(1, reference.num_writers) async def initialize(self): """Create the necessary tables if they don't exist.""" - self.sql_store = AuthorizedSqlStore(sqlstore_impl(self.sql_store_config), self.policy) + base_store = sqlstore_impl(self.reference) + self.sql_store = AuthorizedSqlStore(base_store, self.policy) + + # Disable write queue for SQLite to avoid concurrency issues + backend_name = self.reference.backend + backend_config = _SQLSTORE_BACKENDS.get(backend_name) + if backend_config is None: + raise ValueError( + f"Unregistered SQL backend '{backend_name}'. Registered backends: {sorted(_SQLSTORE_BACKENDS)}" + ) + self.enable_write_queue = backend_config.type != StorageBackendType.SQL_SQLITE await self.sql_store.create_table( "chat_completions", { diff --git a/llama_stack/providers/utils/kvstore/config.py b/llama_stack/providers/utils/kvstore/config.py index 7b6a79350..c0582abc4 100644 --- a/llama_stack/providers/utils/kvstore/config.py +++ b/llama_stack/providers/utils/kvstore/config.py @@ -4,143 +4,20 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -import re -from enum import Enum -from typing import Annotated, Literal +from typing import Annotated -from pydantic import BaseModel, Field, field_validator - -from llama_stack.core.utils.config_dirs import RUNTIME_BASE_DIR - - -class KVStoreType(Enum): - redis = "redis" - sqlite = "sqlite" - postgres = "postgres" - mongodb = "mongodb" - - -class CommonConfig(BaseModel): - namespace: str | None = Field( - default=None, - description="All keys will be prefixed with this namespace", - ) - - -class RedisKVStoreConfig(CommonConfig): - type: Literal["redis"] = KVStoreType.redis.value - host: str = "localhost" - port: int = 6379 - - @property - def url(self) -> str: - return f"redis://{self.host}:{self.port}" - - @classmethod - def pip_packages(cls) -> list[str]: - return ["redis"] - - @classmethod - def sample_run_config(cls): - return { - "type": "redis", - "host": "${env.REDIS_HOST:=localhost}", - "port": "${env.REDIS_PORT:=6379}", - } - - -class SqliteKVStoreConfig(CommonConfig): - type: Literal["sqlite"] = KVStoreType.sqlite.value - db_path: str = Field( - default=(RUNTIME_BASE_DIR / "kvstore.db").as_posix(), - description="File path for the sqlite database", - ) - - @classmethod - def pip_packages(cls) -> list[str]: - return ["aiosqlite"] - - @classmethod - def sample_run_config(cls, __distro_dir__: str, db_name: str = "kvstore.db"): - return { - "type": "sqlite", - "db_path": "${env.SQLITE_STORE_DIR:=" + __distro_dir__ + "}/" + db_name, - } - - -class PostgresKVStoreConfig(CommonConfig): - type: Literal["postgres"] = KVStoreType.postgres.value - host: str = "localhost" - port: int = 5432 - db: str = "llamastack" - user: str - password: str | None = None - ssl_mode: str | None = None - ca_cert_path: str | None = None - table_name: str = "llamastack_kvstore" - - @classmethod - def sample_run_config(cls, table_name: str = "llamastack_kvstore", **kwargs): - return { - "type": "postgres", - "host": "${env.POSTGRES_HOST:=localhost}", - "port": "${env.POSTGRES_PORT:=5432}", - "db": "${env.POSTGRES_DB:=llamastack}", - "user": "${env.POSTGRES_USER:=llamastack}", - "password": "${env.POSTGRES_PASSWORD:=llamastack}", - "table_name": "${env.POSTGRES_TABLE_NAME:=" + table_name + "}", - } - - @classmethod - @field_validator("table_name") - def validate_table_name(cls, v: str) -> str: - # PostgreSQL identifiers rules: - # - Must start with a letter or underscore - # - Can contain letters, numbers, and underscores - # - Maximum length is 63 bytes - pattern = r"^[a-zA-Z_][a-zA-Z0-9_]*$" - if not re.match(pattern, v): - raise ValueError( - "Invalid table name. Must start with letter or underscore and contain only letters, numbers, and underscores" - ) - if len(v) > 63: - raise ValueError("Table name must be less than 63 characters") - return v - - @classmethod - def pip_packages(cls) -> list[str]: - return ["psycopg2-binary"] - - -class MongoDBKVStoreConfig(CommonConfig): - type: Literal["mongodb"] = KVStoreType.mongodb.value - host: str = "localhost" - port: int = 27017 - db: str = "llamastack" - user: str | None = None - password: str | None = None - collection_name: str = "llamastack_kvstore" - - @classmethod - def pip_packages(cls) -> list[str]: - return ["pymongo"] - - @classmethod - def sample_run_config(cls, collection_name: str = "llamastack_kvstore"): - return { - "type": "mongodb", - "host": "${env.MONGODB_HOST:=localhost}", - "port": "${env.MONGODB_PORT:=5432}", - "db": "${env.MONGODB_DB}", - "user": "${env.MONGODB_USER}", - "password": "${env.MONGODB_PASSWORD}", - "collection_name": "${env.MONGODB_COLLECTION_NAME:=" + collection_name + "}", - } +from pydantic import Field +from llama_stack.core.storage.datatypes import ( + MongoDBKVStoreConfig, + PostgresKVStoreConfig, + RedisKVStoreConfig, + SqliteKVStoreConfig, + StorageBackendType, +) KVStoreConfig = Annotated[ - RedisKVStoreConfig | SqliteKVStoreConfig | PostgresKVStoreConfig | MongoDBKVStoreConfig, - Field(discriminator="type", default=KVStoreType.sqlite.value), + RedisKVStoreConfig | SqliteKVStoreConfig | PostgresKVStoreConfig | MongoDBKVStoreConfig, Field(discriminator="type") ] @@ -148,13 +25,13 @@ def get_pip_packages(store_config: dict | KVStoreConfig) -> list[str]: """Get pip packages for KV store config, handling both dict and object cases.""" if isinstance(store_config, dict): store_type = store_config.get("type") - if store_type == "sqlite": + if store_type == StorageBackendType.KV_SQLITE.value: return SqliteKVStoreConfig.pip_packages() - elif store_type == "postgres": + elif store_type == StorageBackendType.KV_POSTGRES.value: return PostgresKVStoreConfig.pip_packages() - elif store_type == "redis": + elif store_type == StorageBackendType.KV_REDIS.value: return RedisKVStoreConfig.pip_packages() - elif store_type == "mongodb": + elif store_type == StorageBackendType.KV_MONGODB.value: return MongoDBKVStoreConfig.pip_packages() else: raise ValueError(f"Unknown KV store type: {store_type}") diff --git a/llama_stack/providers/utils/kvstore/kvstore.py b/llama_stack/providers/utils/kvstore/kvstore.py index 426523d8e..eee51e5d9 100644 --- a/llama_stack/providers/utils/kvstore/kvstore.py +++ b/llama_stack/providers/utils/kvstore/kvstore.py @@ -4,9 +4,17 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +from __future__ import annotations + +from llama_stack.core.storage.datatypes import KVStoreReference, StorageBackendConfig, StorageBackendType from .api import KVStore -from .config import KVStoreConfig, KVStoreType +from .config import KVStoreConfig def kvstore_dependencies(): @@ -44,20 +52,41 @@ class InmemoryKVStoreImpl(KVStore): del self._store[key] -async def kvstore_impl(config: KVStoreConfig) -> KVStore: - if config.type == KVStoreType.redis.value: +_KVSTORE_BACKENDS: dict[str, KVStoreConfig] = {} + + +def register_kvstore_backends(backends: dict[str, StorageBackendConfig]) -> None: + """Register the set of available KV store backends for reference resolution.""" + global _KVSTORE_BACKENDS + + _KVSTORE_BACKENDS.clear() + for name, cfg in backends.items(): + _KVSTORE_BACKENDS[name] = cfg + + +async def kvstore_impl(reference: KVStoreReference) -> KVStore: + backend_name = reference.backend + + backend_config = _KVSTORE_BACKENDS.get(backend_name) + if backend_config is None: + raise ValueError(f"Unknown KVStore backend '{backend_name}'. Registered backends: {sorted(_KVSTORE_BACKENDS)}") + + config = backend_config.model_copy() + config.namespace = reference.namespace + + if config.type == StorageBackendType.KV_REDIS.value: from .redis import RedisKVStoreImpl impl = RedisKVStoreImpl(config) - elif config.type == KVStoreType.sqlite.value: + elif config.type == StorageBackendType.KV_SQLITE.value: from .sqlite import SqliteKVStoreImpl impl = SqliteKVStoreImpl(config) - elif config.type == KVStoreType.postgres.value: + elif config.type == StorageBackendType.KV_POSTGRES.value: from .postgres import PostgresKVStoreImpl impl = PostgresKVStoreImpl(config) - elif config.type == KVStoreType.mongodb.value: + elif config.type == StorageBackendType.KV_MONGODB.value: from .mongodb import MongoDBKVStoreImpl impl = MongoDBKVStoreImpl(config) diff --git a/llama_stack/providers/utils/memory/openai_vector_store_mixin.py b/llama_stack/providers/utils/memory/openai_vector_store_mixin.py index 0e550434e..8f9fb9fb4 100644 --- a/llama_stack/providers/utils/memory/openai_vector_store_mixin.py +++ b/llama_stack/providers/utils/memory/openai_vector_store_mixin.py @@ -17,8 +17,6 @@ from pydantic import TypeAdapter from llama_stack.apis.common.errors import VectorStoreNotFoundError from llama_stack.apis.files import Files, OpenAIFileObject -from llama_stack.apis.models import Model, Models -from llama_stack.apis.vector_dbs import VectorDB from llama_stack.apis.vector_io import ( Chunk, OpenAICreateVectorStoreFileBatchRequestWithExtraBody, @@ -44,6 +42,7 @@ from llama_stack.apis.vector_io import ( VectorStoreSearchResponse, VectorStoreSearchResponsePage, ) +from llama_stack.apis.vector_stores import VectorStore from llama_stack.core.id_generation import generate_object_id from llama_stack.log import get_logger from llama_stack.providers.utils.kvstore.api import KVStore @@ -64,7 +63,7 @@ MAX_CONCURRENT_FILES_PER_BATCH = 3 # Maximum concurrent file processing within FILE_BATCH_CHUNK_SIZE = 10 # Process files in chunks of this size VERSION = "v3" -VECTOR_DBS_PREFIX = f"vector_dbs:{VERSION}::" +VECTOR_DBS_PREFIX = f"vector_stores:{VERSION}::" OPENAI_VECTOR_STORES_PREFIX = f"openai_vector_stores:{VERSION}::" OPENAI_VECTOR_STORES_FILES_PREFIX = f"openai_vector_stores_files:{VERSION}::" OPENAI_VECTOR_STORES_FILES_CONTENTS_PREFIX = f"openai_vector_stores_files_contents:{VERSION}::" @@ -81,13 +80,14 @@ class OpenAIVectorStoreMixin(ABC): # Implementing classes should call super().__init__() in their __init__ method # to properly initialize the mixin attributes. def __init__( - self, files_api: Files | None = None, kvstore: KVStore | None = None, models_api: Models | None = None + self, + files_api: Files | None = None, + kvstore: KVStore | None = None, ): self.openai_vector_stores: dict[str, dict[str, Any]] = {} self.openai_file_batches: dict[str, dict[str, Any]] = {} self.files_api = files_api self.kvstore = kvstore - self.models_api = models_api self._last_file_batch_cleanup_time = 0 self._file_batch_tasks: dict[str, asyncio.Task[None]] = {} @@ -321,12 +321,12 @@ class OpenAIVectorStoreMixin(ABC): pass @abstractmethod - async def register_vector_db(self, vector_db: VectorDB) -> None: + async def register_vector_store(self, vector_store: VectorStore) -> None: """Register a vector database (provider-specific implementation).""" pass @abstractmethod - async def unregister_vector_db(self, vector_db_id: str) -> None: + async def unregister_vector_store(self, vector_store_id: str) -> None: """Unregister a vector database (provider-specific implementation).""" pass @@ -358,7 +358,7 @@ class OpenAIVectorStoreMixin(ABC): extra_body = params.model_extra or {} metadata = params.metadata or {} - provider_vector_db_id = extra_body.get("provider_vector_db_id") + provider_vector_store_id = extra_body.get("provider_vector_store_id") # Use embedding info from metadata if available, otherwise from extra_body if metadata.get("embedding_model"): @@ -370,16 +370,6 @@ class OpenAIVectorStoreMixin(ABC): logger.debug( f"Using embedding config from metadata (takes precedence over extra_body): model='{embedding_model}', dimension={embedding_dimension}" ) - - # Check for conflicts with extra_body - if extra_body.get("embedding_model") and extra_body["embedding_model"] != embedding_model: - raise ValueError( - f"Embedding model inconsistent between metadata ('{embedding_model}') and extra_body ('{extra_body['embedding_model']}')" - ) - if extra_body.get("embedding_dimension") and extra_body["embedding_dimension"] != embedding_dimension: - raise ValueError( - f"Embedding dimension inconsistent between metadata ({embedding_dimension}) and extra_body ({extra_body['embedding_dimension']})" - ) else: embedding_model = extra_body.get("embedding_model") embedding_dimension = extra_body.get("embedding_dimension", EMBEDDING_DIMENSION) @@ -389,42 +379,29 @@ class OpenAIVectorStoreMixin(ABC): # use provider_id set by router; fallback to provider's own ID when used directly via --stack-config provider_id = extra_body.get("provider_id") or getattr(self, "__provider_id__", None) - # Derive the canonical vector_db_id (allow override, else generate) - vector_db_id = provider_vector_db_id or generate_object_id("vector_store", lambda: f"vs_{uuid.uuid4()}") + # Derive the canonical vector_store_id (allow override, else generate) + vector_store_id = provider_vector_store_id or generate_object_id("vector_store", lambda: f"vs_{uuid.uuid4()}") if embedding_model is None: - result = await self._get_default_embedding_model_and_dimension() - if result is None: - raise ValueError( - "embedding_model is required in extra_body when creating a vector store. " - "No default embedding model could be determined automatically." - ) - embedding_model, embedding_dimension = result - elif embedding_dimension is None: - # Embedding model was provided but dimension wasn't, look it up - embedding_dimension = await self._get_embedding_dimension_for_model(embedding_model) - if embedding_dimension is None: - raise ValueError( - f"Could not determine embedding dimension for model '{embedding_model}'. " - "Please provide embedding_dimension in extra_body or ensure the model metadata contains embedding_dimension." - ) + raise ValueError("embedding_model is required") if embedding_dimension is None: raise ValueError("Embedding dimension is required") - # Register the VectorDB backing this vector store + # Register the VectorStore backing this vector store if provider_id is None: raise ValueError("Provider ID is required but was not provided") - vector_db = VectorDB( - identifier=vector_db_id, + # call to the provider to create any index, etc. + vector_store = VectorStore( + identifier=vector_store_id, embedding_dimension=embedding_dimension, embedding_model=embedding_model, provider_id=provider_id, - provider_resource_id=vector_db_id, - vector_db_name=params.name, + provider_resource_id=vector_store_id, + vector_store_name=params.name, ) - await self.register_vector_db(vector_db) + await self.register_vector_store(vector_store) # Create OpenAI vector store metadata status = "completed" @@ -438,7 +415,7 @@ class OpenAIVectorStoreMixin(ABC): total=0, ) store_info: dict[str, Any] = { - "id": vector_db_id, + "id": vector_store_id, "object": "vector_store", "created_at": created_at, "name": params.name, @@ -455,104 +432,25 @@ class OpenAIVectorStoreMixin(ABC): # Add provider information to metadata if provided if provider_id: metadata["provider_id"] = provider_id - if provider_vector_db_id: - metadata["provider_vector_db_id"] = provider_vector_db_id + if provider_vector_store_id: + metadata["provider_vector_store_id"] = provider_vector_store_id store_info["metadata"] = metadata # Save to persistent storage (provider-specific) - await self._save_openai_vector_store(vector_db_id, store_info) + await self._save_openai_vector_store(vector_store_id, store_info) # Store in memory cache - self.openai_vector_stores[vector_db_id] = store_info + self.openai_vector_stores[vector_store_id] = store_info # Now that our vector store is created, attach any files that were provided file_ids = params.file_ids or [] - tasks = [self.openai_attach_file_to_vector_store(vector_db_id, file_id) for file_id in file_ids] + tasks = [self.openai_attach_file_to_vector_store(vector_store_id, file_id) for file_id in file_ids] await asyncio.gather(*tasks) # Get the updated store info and return it - store_info = self.openai_vector_stores[vector_db_id] + store_info = self.openai_vector_stores[vector_store_id] return VectorStoreObject.model_validate(store_info) - async def _get_embedding_models(self) -> list[Model]: - """Get list of embedding models from the models API.""" - if not self.models_api: - return [] - - models_response = await self.models_api.list_models() - models_list = models_response.data if hasattr(models_response, "data") else models_response - - embedding_models = [] - for model in models_list: - if not isinstance(model, Model): - logger.warning(f"Non-Model object found in models list: {type(model)} - {model}") - continue - if model.model_type == "embedding": - embedding_models.append(model) - - return embedding_models - - async def _get_embedding_dimension_for_model(self, model_id: str) -> int | None: - """Get embedding dimension for a specific model by looking it up in the models API. - - Args: - model_id: The identifier of the embedding model (supports both prefixed and non-prefixed) - - Returns: - The embedding dimension for the model, or None if not found - """ - embedding_models = await self._get_embedding_models() - - for model in embedding_models: - # Check for exact match first - if model.identifier == model_id: - embedding_dimension = model.metadata.get("embedding_dimension") - if embedding_dimension is not None: - return int(embedding_dimension) - else: - logger.warning(f"Model {model_id} found but has no embedding_dimension in metadata") - return None - - # Check for prefixed/unprefixed variations - # If model_id is unprefixed, check if it matches the resource_id - if model.provider_resource_id == model_id: - embedding_dimension = model.metadata.get("embedding_dimension") - if embedding_dimension is not None: - return int(embedding_dimension) - - return None - - async def _get_default_embedding_model_and_dimension(self) -> tuple[str, int] | None: - """Get default embedding model from the models API. - - Looks for embedding models marked with default_configured=True in metadata. - Returns None if no default embedding model is found. - Raises ValueError if multiple defaults are found. - """ - embedding_models = await self._get_embedding_models() - - default_models = [] - for model in embedding_models: - if model.metadata.get("default_configured") is True: - default_models.append(model.identifier) - - if len(default_models) > 1: - raise ValueError( - f"Multiple embedding models marked as default_configured=True: {default_models}. " - "Only one embedding model can be marked as default." - ) - - if default_models: - model_id = default_models[0] - embedding_dimension = await self._get_embedding_dimension_for_model(model_id) - if embedding_dimension is None: - raise ValueError(f"Embedding model '{model_id}' has no embedding_dimension in metadata") - logger.info(f"Using default embedding model: {model_id} with dimension {embedding_dimension}") - return model_id, embedding_dimension - - logger.debug("No default embedding models found") - return None - async def openai_list_vector_stores( self, limit: int | None = 20, @@ -660,7 +558,7 @@ class OpenAIVectorStoreMixin(ABC): # Also delete the underlying vector DB try: - await self.unregister_vector_db(vector_store_id) + await self.unregister_vector_store(vector_store_id) except Exception as e: logger.warning(f"Failed to delete underlying vector DB {vector_store_id}: {e}") diff --git a/llama_stack/providers/utils/memory/vector_store.py b/llama_stack/providers/utils/memory/vector_store.py index 0375ecaaa..6c8746e92 100644 --- a/llama_stack/providers/utils/memory/vector_store.py +++ b/llama_stack/providers/utils/memory/vector_store.py @@ -23,8 +23,8 @@ from llama_stack.apis.common.content_types import ( ) from llama_stack.apis.inference import OpenAIEmbeddingsRequestWithExtraBody from llama_stack.apis.tools import RAGDocument -from llama_stack.apis.vector_dbs import VectorDB from llama_stack.apis.vector_io import Chunk, ChunkMetadata, QueryChunksResponse +from llama_stack.apis.vector_stores import VectorStore from llama_stack.log import get_logger from llama_stack.models.llama.llama3.tokenizer import Tokenizer from llama_stack.providers.datatypes import Api @@ -187,7 +187,7 @@ def make_overlapped_chunks( updated_timestamp=int(time.time()), chunk_window=chunk_window, chunk_tokenizer=default_tokenizer, - chunk_embedding_model=None, # This will be set in `VectorDBWithIndex.insert_chunks` + chunk_embedding_model=None, # This will be set in `VectorStoreWithIndex.insert_chunks` content_token_count=len(toks), metadata_token_count=len(metadata_tokens), ) @@ -255,8 +255,8 @@ class EmbeddingIndex(ABC): @dataclass -class VectorDBWithIndex: - vector_db: VectorDB +class VectorStoreWithIndex: + vector_store: VectorStore index: EmbeddingIndex inference_api: Api.inference @@ -269,14 +269,14 @@ class VectorDBWithIndex: if c.embedding is None: chunks_to_embed.append(c) if c.chunk_metadata: - c.chunk_metadata.chunk_embedding_model = self.vector_db.embedding_model - c.chunk_metadata.chunk_embedding_dimension = self.vector_db.embedding_dimension + c.chunk_metadata.chunk_embedding_model = self.vector_store.embedding_model + c.chunk_metadata.chunk_embedding_dimension = self.vector_store.embedding_dimension else: - _validate_embedding(c.embedding, i, self.vector_db.embedding_dimension) + _validate_embedding(c.embedding, i, self.vector_store.embedding_dimension) if chunks_to_embed: params = OpenAIEmbeddingsRequestWithExtraBody( - model=self.vector_db.embedding_model, + model=self.vector_store.embedding_model, input=[c.content for c in chunks_to_embed], ) resp = await self.inference_api.openai_embeddings(params) @@ -319,7 +319,7 @@ class VectorDBWithIndex: return await self.index.query_keyword(query_string, k, score_threshold) params = OpenAIEmbeddingsRequestWithExtraBody( - model=self.vector_db.embedding_model, + model=self.vector_store.embedding_model, input=[query_string], ) embeddings_response = await self.inference_api.openai_embeddings(params) diff --git a/llama_stack/providers/utils/responses/responses_store.py b/llama_stack/providers/utils/responses/responses_store.py index 36370b492..d5c243252 100644 --- a/llama_stack/providers/utils/responses/responses_store.py +++ b/llama_stack/providers/utils/responses/responses_store.py @@ -18,13 +18,13 @@ from llama_stack.apis.agents.openai_responses import ( OpenAIResponseObjectWithInput, ) from llama_stack.apis.inference import OpenAIMessageParam -from llama_stack.core.datatypes import AccessRule, ResponsesStoreConfig -from llama_stack.core.utils.config_dirs import RUNTIME_BASE_DIR +from llama_stack.core.datatypes import AccessRule +from llama_stack.core.storage.datatypes import ResponsesStoreReference, SqlStoreReference, StorageBackendType from llama_stack.log import get_logger from ..sqlstore.api import ColumnDefinition, ColumnType from ..sqlstore.authorized_sqlstore import AuthorizedSqlStore -from ..sqlstore.sqlstore import SqliteSqlStoreConfig, SqlStoreConfig, SqlStoreType, sqlstore_impl +from ..sqlstore.sqlstore import _SQLSTORE_BACKENDS, sqlstore_impl logger = get_logger(name=__name__, category="openai_responses") @@ -45,39 +45,38 @@ class _OpenAIResponseObjectWithInputAndMessages(OpenAIResponseObjectWithInput): class ResponsesStore: def __init__( self, - config: ResponsesStoreConfig | SqlStoreConfig, + reference: ResponsesStoreReference | SqlStoreReference, policy: list[AccessRule], ): - # Handle backward compatibility - if not isinstance(config, ResponsesStoreConfig): - # Legacy: SqlStoreConfig passed directly as config - config = ResponsesStoreConfig( - sql_store_config=config, - ) + if isinstance(reference, ResponsesStoreReference): + self.reference = reference + else: + self.reference = ResponsesStoreReference(**reference.model_dump()) - self.config = config - self.sql_store_config = config.sql_store_config - if not self.sql_store_config: - self.sql_store_config = SqliteSqlStoreConfig( - db_path=(RUNTIME_BASE_DIR / "sqlstore.db").as_posix(), - ) - self.sql_store = None self.policy = policy - - # Disable write queue for SQLite to avoid concurrency issues - self.enable_write_queue = self.sql_store_config.type != SqlStoreType.sqlite + self.sql_store = None + self.enable_write_queue = True # Async write queue and worker control self._queue: ( asyncio.Queue[tuple[OpenAIResponseObject, list[OpenAIResponseInput], list[OpenAIMessageParam]]] | None ) = None self._worker_tasks: list[asyncio.Task[Any]] = [] - self._max_write_queue_size: int = config.max_write_queue_size - self._num_writers: int = max(1, config.num_writers) + self._max_write_queue_size: int = self.reference.max_write_queue_size + self._num_writers: int = max(1, self.reference.num_writers) async def initialize(self): """Create the necessary tables if they don't exist.""" - self.sql_store = AuthorizedSqlStore(sqlstore_impl(self.sql_store_config), self.policy) + base_store = sqlstore_impl(self.reference) + self.sql_store = AuthorizedSqlStore(base_store, self.policy) + + backend_config = _SQLSTORE_BACKENDS.get(self.reference.backend) + if backend_config is None: + raise ValueError( + f"Unregistered SQL backend '{self.reference.backend}'. Registered backends: {sorted(_SQLSTORE_BACKENDS)}" + ) + if backend_config.type == StorageBackendType.SQL_SQLITE: + self.enable_write_queue = False await self.sql_store.create_table( "openai_responses", { diff --git a/llama_stack/providers/utils/sqlstore/authorized_sqlstore.py b/llama_stack/providers/utils/sqlstore/authorized_sqlstore.py index e1da4db6e..3dfc82677 100644 --- a/llama_stack/providers/utils/sqlstore/authorized_sqlstore.py +++ b/llama_stack/providers/utils/sqlstore/authorized_sqlstore.py @@ -12,10 +12,10 @@ from llama_stack.core.access_control.conditions import ProtectedResource from llama_stack.core.access_control.datatypes import AccessRule, Action, Scope from llama_stack.core.datatypes import User from llama_stack.core.request_headers import get_authenticated_user +from llama_stack.core.storage.datatypes import StorageBackendType from llama_stack.log import get_logger from .api import ColumnDefinition, ColumnType, PaginatedResponse, SqlStore -from .sqlstore import SqlStoreType logger = get_logger(name=__name__, category="providers::utils") @@ -82,8 +82,8 @@ class AuthorizedSqlStore: if not hasattr(self.sql_store, "config"): raise ValueError("SqlStore must have a config attribute to be used with AuthorizedSqlStore") - self.database_type = self.sql_store.config.type - if self.database_type not in [SqlStoreType.postgres, SqlStoreType.sqlite]: + self.database_type = self.sql_store.config.type.value + if self.database_type not in [StorageBackendType.SQL_POSTGRES.value, StorageBackendType.SQL_SQLITE.value]: raise ValueError(f"Unsupported database type: {self.database_type}") def _validate_sql_optimized_policy(self) -> None: @@ -220,9 +220,9 @@ class AuthorizedSqlStore: Returns: SQL expression to extract JSON value """ - if self.database_type == SqlStoreType.postgres: + if self.database_type == StorageBackendType.SQL_POSTGRES.value: return f"{column}->'{path}'" - elif self.database_type == SqlStoreType.sqlite: + elif self.database_type == StorageBackendType.SQL_SQLITE.value: return f"JSON_EXTRACT({column}, '$.{path}')" else: raise ValueError(f"Unsupported database type: {self.database_type}") @@ -237,9 +237,9 @@ class AuthorizedSqlStore: Returns: SQL expression to extract JSON value as text """ - if self.database_type == SqlStoreType.postgres: + if self.database_type == StorageBackendType.SQL_POSTGRES.value: return f"{column}->>'{path}'" - elif self.database_type == SqlStoreType.sqlite: + elif self.database_type == StorageBackendType.SQL_SQLITE.value: return f"JSON_EXTRACT({column}, '$.{path}')" else: raise ValueError(f"Unsupported database type: {self.database_type}") @@ -248,10 +248,10 @@ class AuthorizedSqlStore: """Get the SQL conditions for public access.""" # Public records are records that have no owner_principal or access_attributes conditions = ["owner_principal = ''"] - if self.database_type == SqlStoreType.postgres: + if self.database_type == StorageBackendType.SQL_POSTGRES.value: # Postgres stores JSON null as 'null' conditions.append("access_attributes::text = 'null'") - elif self.database_type == SqlStoreType.sqlite: + elif self.database_type == StorageBackendType.SQL_SQLITE.value: conditions.append("access_attributes = 'null'") else: raise ValueError(f"Unsupported database type: {self.database_type}") diff --git a/llama_stack/providers/utils/sqlstore/sqlalchemy_sqlstore.py b/llama_stack/providers/utils/sqlstore/sqlalchemy_sqlstore.py index 23cd6444e..c1ccd73dd 100644 --- a/llama_stack/providers/utils/sqlstore/sqlalchemy_sqlstore.py +++ b/llama_stack/providers/utils/sqlstore/sqlalchemy_sqlstore.py @@ -26,10 +26,10 @@ from sqlalchemy.ext.asyncio.engine import AsyncEngine from sqlalchemy.sql.elements import ColumnElement from llama_stack.apis.common.responses import PaginatedResponse +from llama_stack.core.storage.datatypes import SqlAlchemySqlStoreConfig from llama_stack.log import get_logger from .api import ColumnDefinition, ColumnType, SqlStore -from .sqlstore import SqlAlchemySqlStoreConfig logger = get_logger(name=__name__, category="providers::utils") diff --git a/llama_stack/providers/utils/sqlstore/sqlstore.py b/llama_stack/providers/utils/sqlstore/sqlstore.py index fc44402ae..31801c4ca 100644 --- a/llama_stack/providers/utils/sqlstore/sqlstore.py +++ b/llama_stack/providers/utils/sqlstore/sqlstore.py @@ -4,90 +4,28 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -from abc import abstractmethod -from enum import StrEnum -from pathlib import Path -from typing import Annotated, Literal +from typing import Annotated, cast -from pydantic import BaseModel, Field +from pydantic import Field -from llama_stack.core.utils.config_dirs import RUNTIME_BASE_DIR +from llama_stack.core.storage.datatypes import ( + PostgresSqlStoreConfig, + SqliteSqlStoreConfig, + SqlStoreReference, + StorageBackendConfig, + StorageBackendType, +) from .api import SqlStore sql_store_pip_packages = ["sqlalchemy[asyncio]", "aiosqlite", "asyncpg"] - -class SqlStoreType(StrEnum): - sqlite = "sqlite" - postgres = "postgres" - - -class SqlAlchemySqlStoreConfig(BaseModel): - @property - @abstractmethod - def engine_str(self) -> str: ... - - # TODO: move this when we have a better way to specify dependencies with internal APIs - @classmethod - def pip_packages(cls) -> list[str]: - return ["sqlalchemy[asyncio]"] - - -class SqliteSqlStoreConfig(SqlAlchemySqlStoreConfig): - type: Literal[SqlStoreType.sqlite] = SqlStoreType.sqlite - db_path: str = Field( - default=(RUNTIME_BASE_DIR / "sqlstore.db").as_posix(), - description="Database path, e.g. ~/.llama/distributions/ollama/sqlstore.db", - ) - - @property - def engine_str(self) -> str: - return "sqlite+aiosqlite:///" + Path(self.db_path).expanduser().as_posix() - - @classmethod - def sample_run_config(cls, __distro_dir__: str, db_name: str = "sqlstore.db"): - return { - "type": "sqlite", - "db_path": "${env.SQLITE_STORE_DIR:=" + __distro_dir__ + "}/" + db_name, - } - - @classmethod - def pip_packages(cls) -> list[str]: - return super().pip_packages() + ["aiosqlite"] - - -class PostgresSqlStoreConfig(SqlAlchemySqlStoreConfig): - type: Literal[SqlStoreType.postgres] = SqlStoreType.postgres - host: str = "localhost" - port: int = 5432 - db: str = "llamastack" - user: str - password: str | None = None - - @property - def engine_str(self) -> str: - return f"postgresql+asyncpg://{self.user}:{self.password}@{self.host}:{self.port}/{self.db}" - - @classmethod - def pip_packages(cls) -> list[str]: - return super().pip_packages() + ["asyncpg"] - - @classmethod - def sample_run_config(cls, **kwargs): - return { - "type": "postgres", - "host": "${env.POSTGRES_HOST:=localhost}", - "port": "${env.POSTGRES_PORT:=5432}", - "db": "${env.POSTGRES_DB:=llamastack}", - "user": "${env.POSTGRES_USER:=llamastack}", - "password": "${env.POSTGRES_PASSWORD:=llamastack}", - } +_SQLSTORE_BACKENDS: dict[str, StorageBackendConfig] = {} SqlStoreConfig = Annotated[ SqliteSqlStoreConfig | PostgresSqlStoreConfig, - Field(discriminator="type", default=SqlStoreType.sqlite.value), + Field(discriminator="type"), ] @@ -95,9 +33,9 @@ def get_pip_packages(store_config: dict | SqlStoreConfig) -> list[str]: """Get pip packages for SQL store config, handling both dict and object cases.""" if isinstance(store_config, dict): store_type = store_config.get("type") - if store_type == "sqlite": + if store_type == StorageBackendType.SQL_SQLITE.value: return SqliteSqlStoreConfig.pip_packages() - elif store_type == "postgres": + elif store_type == StorageBackendType.SQL_POSTGRES.value: return PostgresSqlStoreConfig.pip_packages() else: raise ValueError(f"Unknown SQL store type: {store_type}") @@ -105,12 +43,28 @@ def get_pip_packages(store_config: dict | SqlStoreConfig) -> list[str]: return store_config.pip_packages() -def sqlstore_impl(config: SqlStoreConfig) -> SqlStore: - if config.type in [SqlStoreType.sqlite, SqlStoreType.postgres]: +def sqlstore_impl(reference: SqlStoreReference) -> SqlStore: + backend_name = reference.backend + + backend_config = _SQLSTORE_BACKENDS.get(backend_name) + if backend_config is None: + raise ValueError( + f"Unknown SQL store backend '{backend_name}'. Registered backends: {sorted(_SQLSTORE_BACKENDS)}" + ) + + if isinstance(backend_config, SqliteSqlStoreConfig | PostgresSqlStoreConfig): from .sqlalchemy_sqlstore import SqlAlchemySqlStoreImpl - impl = SqlAlchemySqlStoreImpl(config) + config = cast(SqliteSqlStoreConfig | PostgresSqlStoreConfig, backend_config).model_copy() + return SqlAlchemySqlStoreImpl(config) else: - raise ValueError(f"Unknown sqlstore type {config.type}") + raise ValueError(f"Unknown sqlstore type {backend_config.type}") - return impl + +def register_sqlstore_backends(backends: dict[str, StorageBackendConfig]) -> None: + """Register the set of available SQL store backends for reference resolution.""" + global _SQLSTORE_BACKENDS + + _SQLSTORE_BACKENDS.clear() + for name, cfg in backends.items(): + _SQLSTORE_BACKENDS[name] = cfg diff --git a/llama_stack/ui/package-lock.json b/llama_stack/ui/package-lock.json index c138de535..8e93fc5ab 100644 --- a/llama_stack/ui/package-lock.json +++ b/llama_stack/ui/package-lock.json @@ -18,7 +18,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "framer-motion": "^12.23.24", - "llama-stack-client": "^0.2.23", + "llama-stack-client": "^0.3.0", "lucide-react": "^0.545.0", "next": "15.5.4", "next-auth": "^4.24.11", @@ -75,20 +75,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, "node_modules/@asamuzakjp/css-color": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", @@ -2072,9 +2058,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, "license": "MIT" }, @@ -3199,61 +3185,54 @@ } }, "node_modules/@tailwindcss/node": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.6.tgz", - "integrity": "sha512-ed6zQbgmKsjsVvodAS1q1Ld2BolEuxJOSyyNc+vhkjdmfNUDCmQnlXBfQkHrlzNmslxHsQU/bFmzcEbv4xXsLg==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.14.tgz", + "integrity": "sha512-hpz+8vFk3Ic2xssIA3e01R6jkmsAhvkQdXlEbRTk6S10xDAtiQiM3FyvZVGsucefq764euO/b8WUW9ysLdThHw==", "dev": true, "license": "MIT", "dependencies": { - "@ampproject/remapping": "^2.3.0", - "enhanced-resolve": "^5.18.1", - "jiti": "^2.4.2", - "lightningcss": "1.29.2", - "magic-string": "^0.30.17", + "@jridgewell/remapping": "^2.3.4", + "enhanced-resolve": "^5.18.3", + "jiti": "^2.6.0", + "lightningcss": "1.30.1", + "magic-string": "^0.30.19", "source-map-js": "^1.2.1", - "tailwindcss": "4.1.6" + "tailwindcss": "4.1.14" } }, - "node_modules/@tailwindcss/node/node_modules/tailwindcss": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.6.tgz", - "integrity": "sha512-j0cGLTreM6u4OWzBeLBpycK0WIh8w7kSwcUsQZoGLHZ7xDTdM69lN64AgoIEEwFi0tnhs4wSykUa5YWxAzgFYg==", - "dev": true, - "license": "MIT" - }, "node_modules/@tailwindcss/oxide": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.6.tgz", - "integrity": "sha512-0bpEBQiGx+227fW4G0fLQ8vuvyy5rsB1YIYNapTq3aRsJ9taF3f5cCaovDjN5pUGKKzcpMrZst/mhNaKAPOHOA==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.14.tgz", + "integrity": "sha512-23yx+VUbBwCg2x5XWdB8+1lkPajzLmALEfMb51zZUBYaYVPDQvBSD/WYDqiVyBIo2BZFa3yw1Rpy3G2Jp+K0dw==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { "detect-libc": "^2.0.4", - "tar": "^7.4.3" + "tar": "^7.5.1" }, "engines": { "node": ">= 10" }, "optionalDependencies": { - "@tailwindcss/oxide-android-arm64": "4.1.6", - "@tailwindcss/oxide-darwin-arm64": "4.1.6", - "@tailwindcss/oxide-darwin-x64": "4.1.6", - "@tailwindcss/oxide-freebsd-x64": "4.1.6", - "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.6", - "@tailwindcss/oxide-linux-arm64-gnu": "4.1.6", - "@tailwindcss/oxide-linux-arm64-musl": "4.1.6", - "@tailwindcss/oxide-linux-x64-gnu": "4.1.6", - "@tailwindcss/oxide-linux-x64-musl": "4.1.6", - "@tailwindcss/oxide-wasm32-wasi": "4.1.6", - "@tailwindcss/oxide-win32-arm64-msvc": "4.1.6", - "@tailwindcss/oxide-win32-x64-msvc": "4.1.6" + "@tailwindcss/oxide-android-arm64": "4.1.14", + "@tailwindcss/oxide-darwin-arm64": "4.1.14", + "@tailwindcss/oxide-darwin-x64": "4.1.14", + "@tailwindcss/oxide-freebsd-x64": "4.1.14", + "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.14", + "@tailwindcss/oxide-linux-arm64-gnu": "4.1.14", + "@tailwindcss/oxide-linux-arm64-musl": "4.1.14", + "@tailwindcss/oxide-linux-x64-gnu": "4.1.14", + "@tailwindcss/oxide-linux-x64-musl": "4.1.14", + "@tailwindcss/oxide-wasm32-wasi": "4.1.14", + "@tailwindcss/oxide-win32-arm64-msvc": "4.1.14", + "@tailwindcss/oxide-win32-x64-msvc": "4.1.14" } }, "node_modules/@tailwindcss/oxide-android-arm64": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.6.tgz", - "integrity": "sha512-VHwwPiwXtdIvOvqT/0/FLH/pizTVu78FOnI9jQo64kSAikFSZT7K4pjyzoDpSMaveJTGyAKvDjuhxJxKfmvjiQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.14.tgz", + "integrity": "sha512-a94ifZrGwMvbdeAxWoSuGcIl6/DOP5cdxagid7xJv6bwFp3oebp7y2ImYsnZBMTwjn5Ev5xESvS3FFYUGgPODQ==", "cpu": [ "arm64" ], @@ -3268,9 +3247,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-arm64": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.6.tgz", - "integrity": "sha512-weINOCcqv1HVBIGptNrk7c6lWgSFFiQMcCpKM4tnVi5x8OY2v1FrV76jwLukfT6pL1hyajc06tyVmZFYXoxvhQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.14.tgz", + "integrity": "sha512-HkFP/CqfSh09xCnrPJA7jud7hij5ahKyWomrC3oiO2U9i0UjP17o9pJbxUN0IJ471GTQQmzwhp0DEcpbp4MZTA==", "cpu": [ "arm64" ], @@ -3285,9 +3264,9 @@ } }, "node_modules/@tailwindcss/oxide-darwin-x64": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.6.tgz", - "integrity": "sha512-3FzekhHG0ww1zQjQ1lPoq0wPrAIVXAbUkWdWM8u5BnYFZgb9ja5ejBqyTgjpo5mfy0hFOoMnMuVDI+7CXhXZaQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.14.tgz", + "integrity": "sha512-eVNaWmCgdLf5iv6Qd3s7JI5SEFBFRtfm6W0mphJYXgvnDEAZ5sZzqmI06bK6xo0IErDHdTA5/t7d4eTfWbWOFw==", "cpu": [ "x64" ], @@ -3302,9 +3281,9 @@ } }, "node_modules/@tailwindcss/oxide-freebsd-x64": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.6.tgz", - "integrity": "sha512-4m5F5lpkBZhVQJq53oe5XgJ+aFYWdrgkMwViHjRsES3KEu2m1udR21B1I77RUqie0ZYNscFzY1v9aDssMBZ/1w==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.14.tgz", + "integrity": "sha512-QWLoRXNikEuqtNb0dhQN6wsSVVjX6dmUFzuuiL09ZeXju25dsei2uIPl71y2Ic6QbNBsB4scwBoFnlBfabHkEw==", "cpu": [ "x64" ], @@ -3319,9 +3298,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.6.tgz", - "integrity": "sha512-qU0rHnA9P/ZoaDKouU1oGPxPWzDKtIfX7eOGi5jOWJKdxieUJdVV+CxWZOpDWlYTd4N3sFQvcnVLJWJ1cLP5TA==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.14.tgz", + "integrity": "sha512-VB4gjQni9+F0VCASU+L8zSIyjrLLsy03sjcR3bM0V2g4SNamo0FakZFKyUQ96ZVwGK4CaJsc9zd/obQy74o0Fw==", "cpu": [ "arm" ], @@ -3336,9 +3315,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-gnu": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.6.tgz", - "integrity": "sha512-jXy3TSTrbfgyd3UxPQeXC3wm8DAgmigzar99Km9Sf6L2OFfn/k+u3VqmpgHQw5QNfCpPe43em6Q7V76Wx7ogIQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.14.tgz", + "integrity": "sha512-qaEy0dIZ6d9vyLnmeg24yzA8XuEAD9WjpM5nIM1sUgQ/Zv7cVkharPDQcmm/t/TvXoKo/0knI3me3AGfdx6w1w==", "cpu": [ "arm64" ], @@ -3353,9 +3332,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-arm64-musl": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.6.tgz", - "integrity": "sha512-8kjivE5xW0qAQ9HX9reVFmZj3t+VmljDLVRJpVBEoTR+3bKMnvC7iLcoSGNIUJGOZy1mLVq7x/gerVg0T+IsYw==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.14.tgz", + "integrity": "sha512-ISZjT44s59O8xKsPEIesiIydMG/sCXoMBCqsphDm/WcbnuWLxxb+GcvSIIA5NjUw6F8Tex7s5/LM2yDy8RqYBQ==", "cpu": [ "arm64" ], @@ -3370,9 +3349,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-gnu": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.6.tgz", - "integrity": "sha512-A4spQhwnWVpjWDLXnOW9PSinO2PTKJQNRmL/aIl2U/O+RARls8doDfs6R41+DAXK0ccacvRyDpR46aVQJJCoCg==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.14.tgz", + "integrity": "sha512-02c6JhLPJj10L2caH4U0zF8Hji4dOeahmuMl23stk0MU1wfd1OraE7rOloidSF8W5JTHkFdVo/O7uRUJJnUAJg==", "cpu": [ "x64" ], @@ -3387,9 +3366,9 @@ } }, "node_modules/@tailwindcss/oxide-linux-x64-musl": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.6.tgz", - "integrity": "sha512-YRee+6ZqdzgiQAHVSLfl3RYmqeeaWVCk796MhXhLQu2kJu2COHBkqlqsqKYx3p8Hmk5pGCQd2jTAoMWWFeyG2A==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.14.tgz", + "integrity": "sha512-TNGeLiN1XS66kQhxHG/7wMeQDOoL0S33x9BgmydbrWAb9Qw0KYdd8o1ifx4HOGDWhVmJ+Ul+JQ7lyknQFilO3Q==", "cpu": [ "x64" ], @@ -3404,9 +3383,9 @@ } }, "node_modules/@tailwindcss/oxide-wasm32-wasi": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.6.tgz", - "integrity": "sha512-qAp4ooTYrBQ5pk5jgg54/U1rCJ/9FLYOkkQ/nTE+bVMseMfB6O7J8zb19YTpWuu4UdfRf5zzOrNKfl6T64MNrQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.14.tgz", + "integrity": "sha512-uZYAsaW/jS/IYkd6EWPJKW/NlPNSkWkBlaeVBi/WsFQNP05/bzkebUL8FH1pdsqx4f2fH/bWFcUABOM9nfiJkQ==", "bundleDependencies": [ "@napi-rs/wasm-runtime", "@emnapi/core", @@ -3422,21 +3401,81 @@ "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@emnapi/wasi-threads": "^1.0.2", - "@napi-rs/wasm-runtime": "^0.2.9", - "@tybys/wasm-util": "^0.9.0", - "tslib": "^2.8.0" + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@emnapi/wasi-threads": "^1.1.0", + "@napi-rs/wasm-runtime": "^1.0.5", + "@tybys/wasm-util": "^0.10.1", + "tslib": "^2.4.0" }, "engines": { "node": ">=14.0.0" } }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.5.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.5.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.5.0", + "@emnapi/runtime": "^1.5.0", + "@tybys/wasm-util": "^0.10.1" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "inBundle": true, + "license": "0BSD", + "optional": true + }, "node_modules/@tailwindcss/oxide-win32-arm64-msvc": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.6.tgz", - "integrity": "sha512-nqpDWk0Xr8ELO/nfRUDjk1pc9wDJ3ObeDdNMHLaymc4PJBWj11gdPCWZFKSK2AVKjJQC7J2EfmSmf47GN7OuLg==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.14.tgz", + "integrity": "sha512-Az0RnnkcvRqsuoLH2Z4n3JfAef0wElgzHD5Aky/e+0tBUxUhIeIqFBTMNQvmMRSP15fWwmvjBxZ3Q8RhsDnxAA==", "cpu": [ "arm64" ], @@ -3451,9 +3490,9 @@ } }, "node_modules/@tailwindcss/oxide-win32-x64-msvc": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.6.tgz", - "integrity": "sha512-5k9xF33xkfKpo9wCvYcegQ21VwIBU1/qEbYlVukfEIyQbEA47uK8AAwS7NVjNE3vHzcmxMYwd0l6L4pPjjm1rQ==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.14.tgz", + "integrity": "sha512-ttblVGHgf68kEE4om1n/n44I0yGPkCPbLsqzjvybhpwa6mKKtgFfAzy6btc3HRmuW7nHe0OOrSeNP9sQmmH9XA==", "cpu": [ "x64" ], @@ -3468,26 +3507,19 @@ } }, "node_modules/@tailwindcss/postcss": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.6.tgz", - "integrity": "sha512-ELq+gDMBuRXPJlpE3PEen+1MhnHAQQrh2zF0dI1NXOlEWfr2qWf2CQdr5jl9yANv8RErQaQ2l6nIFO9OSCVq/g==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.1.14.tgz", + "integrity": "sha512-BdMjIxy7HUNThK87C7BC8I1rE8BVUsfNQSI5siQ4JK3iIa3w0XyVvVL9SXLWO//CtYTcp1v7zci0fYwJOjB+Zg==", "dev": true, "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", - "@tailwindcss/node": "4.1.6", - "@tailwindcss/oxide": "4.1.6", + "@tailwindcss/node": "4.1.14", + "@tailwindcss/oxide": "4.1.14", "postcss": "^8.4.41", - "tailwindcss": "4.1.6" + "tailwindcss": "4.1.14" } }, - "node_modules/@tailwindcss/postcss/node_modules/tailwindcss": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.6.tgz", - "integrity": "sha512-j0cGLTreM6u4OWzBeLBpycK0WIh8w7kSwcUsQZoGLHZ7xDTdM69lN64AgoIEEwFi0tnhs4wSykUa5YWxAzgFYg==", - "dev": true, - "license": "MIT" - }, "node_modules/@testing-library/dom": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", @@ -3601,17 +3633,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", - "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@types/aria-query": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", @@ -3812,12 +3833,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "24.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz", - "integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==", + "version": "24.8.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.8.1.tgz", + "integrity": "sha512-alv65KGRadQVfVcG69MuB4IzdYVpRwMG/mq8KWOaoOdyY617P5ivaDiMCGOFDWD2sAn5Q0mR3mRtUOgm99hL9Q==", "license": "MIT", "dependencies": { - "undici-types": "~7.10.0" + "undici-types": "~7.14.0" } }, "node_modules/@types/node-fetch": { @@ -5850,9 +5871,9 @@ "license": "MIT" }, "node_modules/enhanced-resolve": { - "version": "5.18.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", - "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", "dev": true, "license": "MIT", "dependencies": { @@ -9128,9 +9149,9 @@ } }, "node_modules/jiti": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", - "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", + "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", "dev": true, "license": "MIT", "bin": { @@ -9368,9 +9389,9 @@ } }, "node_modules/lightningcss": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz", - "integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.1.tgz", + "integrity": "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg==", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -9384,22 +9405,22 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "lightningcss-darwin-arm64": "1.29.2", - "lightningcss-darwin-x64": "1.29.2", - "lightningcss-freebsd-x64": "1.29.2", - "lightningcss-linux-arm-gnueabihf": "1.29.2", - "lightningcss-linux-arm64-gnu": "1.29.2", - "lightningcss-linux-arm64-musl": "1.29.2", - "lightningcss-linux-x64-gnu": "1.29.2", - "lightningcss-linux-x64-musl": "1.29.2", - "lightningcss-win32-arm64-msvc": "1.29.2", - "lightningcss-win32-x64-msvc": "1.29.2" + "lightningcss-darwin-arm64": "1.30.1", + "lightningcss-darwin-x64": "1.30.1", + "lightningcss-freebsd-x64": "1.30.1", + "lightningcss-linux-arm-gnueabihf": "1.30.1", + "lightningcss-linux-arm64-gnu": "1.30.1", + "lightningcss-linux-arm64-musl": "1.30.1", + "lightningcss-linux-x64-gnu": "1.30.1", + "lightningcss-linux-x64-musl": "1.30.1", + "lightningcss-win32-arm64-msvc": "1.30.1", + "lightningcss-win32-x64-msvc": "1.30.1" } }, "node_modules/lightningcss-darwin-arm64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz", - "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.30.1.tgz", + "integrity": "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ==", "cpu": [ "arm64" ], @@ -9418,9 +9439,9 @@ } }, "node_modules/lightningcss-darwin-x64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz", - "integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.30.1.tgz", + "integrity": "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA==", "cpu": [ "x64" ], @@ -9439,9 +9460,9 @@ } }, "node_modules/lightningcss-freebsd-x64": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz", - "integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.30.1.tgz", + "integrity": "sha512-kmW6UGCGg2PcyUE59K5r0kWfKPAVy4SltVeut+umLCFoJ53RdCUWxcRDzO1eTaxf/7Q2H7LTquFHPL5R+Gjyig==", "cpu": [ "x64" ], @@ -9460,9 +9481,9 @@ } }, "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz", - "integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.30.1.tgz", + "integrity": "sha512-MjxUShl1v8pit+6D/zSPq9S9dQ2NPFSQwGvxBCYaBYLPlCWuPh9/t1MRS8iUaR8i+a6w7aps+B4N0S1TYP/R+Q==", "cpu": [ "arm" ], @@ -9481,9 +9502,9 @@ } }, "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz", - "integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.30.1.tgz", + "integrity": "sha512-gB72maP8rmrKsnKYy8XUuXi/4OctJiuQjcuqWNlJQ6jZiWqtPvqFziskH3hnajfvKB27ynbVCucKSm2rkQp4Bw==", "cpu": [ "arm64" ], @@ -9502,9 +9523,9 @@ } }, "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz", - "integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.30.1.tgz", + "integrity": "sha512-jmUQVx4331m6LIX+0wUhBbmMX7TCfjF5FoOH6SD1CttzuYlGNVpA7QnrmLxrsub43ClTINfGSYyHe2HWeLl5CQ==", "cpu": [ "arm64" ], @@ -9523,9 +9544,9 @@ } }, "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz", - "integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.30.1.tgz", + "integrity": "sha512-piWx3z4wN8J8z3+O5kO74+yr6ze/dKmPnI7vLqfSqI8bccaTGY5xiSGVIJBDd5K5BHlvVLpUB3S2YCfelyJ1bw==", "cpu": [ "x64" ], @@ -9544,9 +9565,9 @@ } }, "node_modules/lightningcss-linux-x64-musl": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz", - "integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.30.1.tgz", + "integrity": "sha512-rRomAK7eIkL+tHY0YPxbc5Dra2gXlI63HL+v1Pdi1a3sC+tJTcFrHX+E86sulgAXeI7rSzDYhPSeHHjqFhqfeQ==", "cpu": [ "x64" ], @@ -9565,9 +9586,9 @@ } }, "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz", - "integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.30.1.tgz", + "integrity": "sha512-mSL4rqPi4iXq5YVqzSsJgMVFENoa4nGTT/GjO2c0Yl9OuQfPsIfncvLrEW6RbbB24WtZ3xP/2CCmI3tNkNV4oA==", "cpu": [ "arm64" ], @@ -9586,9 +9607,9 @@ } }, "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.29.2", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz", - "integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==", + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.30.1.tgz", + "integrity": "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg==", "cpu": [ "x64" ], @@ -9614,9 +9635,9 @@ "license": "MIT" }, "node_modules/llama-stack-client": { - "version": "0.2.23", - "resolved": "https://registry.npmjs.org/llama-stack-client/-/llama-stack-client-0.2.23.tgz", - "integrity": "sha512-J3YFH1HW2K70capejQxGlCyTgKdfx+sQf8Ab+HFi1j2Q00KtpHXB79RxejvBxjWC3X2E++P9iU57KdU2Tp/rIQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/llama-stack-client/-/llama-stack-client-0.3.0.tgz", + "integrity": "sha512-76K/t1doaGmlBbDxCADaral9Vccvys9P8pqAMIhwBhMAqWudCEORrMMhUSg+pjhamWmEKj3wa++d4zeOGbfN/w==", "license": "MIT", "dependencies": { "@types/node": "^18.11.18", @@ -9726,13 +9747,13 @@ } }, "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "version": "0.30.19", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.19.tgz", + "integrity": "sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/make-dir": { @@ -10717,9 +10738,9 @@ } }, "node_modules/minizlib": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", - "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", "dev": true, "license": "MIT", "dependencies": { @@ -10729,22 +10750,6 @@ "node": ">= 18" } }, - "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/motion-dom": { "version": "12.23.23", "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.23.tgz", @@ -12989,34 +12994,37 @@ } }, "node_modules/tailwindcss": { - "version": "4.1.13", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.13.tgz", - "integrity": "sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==", + "version": "4.1.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.14.tgz", + "integrity": "sha512-b7pCxjGO98LnxVkKjaZSDeNuljC4ueKUddjENJOADtubtdo8llTaJy7HwBMeLNSSo2N5QIAgklslK1+Ir8r6CA==", "dev": true, "license": "MIT" }, "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.1.tgz", + "integrity": "sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==", "dev": true, "license": "ISC", "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", + "minizlib": "^3.1.0", "yallist": "^5.0.0" }, "engines": { @@ -13418,9 +13426,9 @@ } }, "node_modules/undici-types": { - "version": "7.10.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz", - "integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.14.0.tgz", + "integrity": "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA==", "license": "MIT" }, "node_modules/unified": { diff --git a/llama_stack/ui/package.json b/llama_stack/ui/package.json index 07b3465e5..9350be16a 100644 --- a/llama_stack/ui/package.json +++ b/llama_stack/ui/package.json @@ -23,7 +23,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "framer-motion": "^12.23.24", - "llama-stack-client": "^0.2.23", + "llama-stack-client": "^0.3.0", "lucide-react": "^0.545.0", "next": "15.5.4", "next-auth": "^4.24.11", diff --git a/pyproject.toml b/pyproject.toml index 1fd3cf0c7..741dd17e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ required-version = ">=0.7.0" [project] name = "llama_stack" -version = "0.3.0rc2" +version = "0.3.0" authors = [{ name = "Meta Llama", email = "llama-oss@meta.com" }] description = "Llama Stack" readme = "README.md" @@ -30,7 +30,7 @@ dependencies = [ "httpx", "jinja2>=3.1.6", "jsonschema", - "llama-stack-client>=0.3.0rc2", + "llama-stack-client>=0.3.0", "openai>=1.107", # for expires_after support "prompt-toolkit", "python-dotenv", @@ -55,7 +55,7 @@ dependencies = [ ui = [ "streamlit", "pandas", - "llama-stack-client>=0.3.0rc2", + "llama-stack-client>=0.3.0", "streamlit-option-menu", ] diff --git a/scripts/docker.sh b/scripts/docker.sh index 1ba1d9adf..a0690c8a9 100755 --- a/scripts/docker.sh +++ b/scripts/docker.sh @@ -156,6 +156,16 @@ DISTRO=$(echo "$DISTRO" | sed 's/^docker://') CONTAINER_NAME="llama-stack-test-$DISTRO" +should_copy_source() { + if [[ "$USE_COPY_NOT_MOUNT" == "true" ]]; then + return 0 + fi + if [[ "${CI:-false}" == "true" ]] || [[ "${GITHUB_ACTIONS:-false}" == "true" ]]; then + return 0 + fi + return 1 +} + # Function to check if container is running is_container_running() { docker ps --filter "name=^${CONTAINER_NAME}$" --format '{{.Names}}' | grep -q "^${CONTAINER_NAME}$" @@ -183,20 +193,29 @@ stop_container() { build_image() { echo "=== Building Docker Image for distribution: $DISTRO ===" # Get the repo root (parent of scripts directory) - SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - REPO_ROOT=$(cd "$SCRIPT_DIR/.." && pwd) + local script_dir + script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) + local repo_root + repo_root=$(cd "$script_dir/.." && pwd) - # Determine whether to copy or mount source - # Copy in CI or if explicitly requested, otherwise mount for live development - BUILD_ENV="LLAMA_STACK_DIR=$REPO_ROOT" - if [[ "$USE_COPY_NOT_MOUNT" == "true" ]] || [[ "${CI:-false}" == "true" ]] || [[ "${GITHUB_ACTIONS:-false}" == "true" ]]; then - echo "Copying source into image (USE_COPY_NOT_MOUNT=true, CI=${CI:-false}, GITHUB_ACTIONS=${GITHUB_ACTIONS:-false})" - BUILD_ENV="USE_COPY_NOT_MOUNT=true $BUILD_ENV" - else - echo "Will mount source for live development" + local containerfile="$repo_root/containers/Containerfile" + if [[ ! -f "$containerfile" ]]; then + echo "❌ Containerfile not found at $containerfile" + exit 1 fi - if ! eval "$BUILD_ENV llama stack build --distro '$DISTRO' --image-type container"; then + local build_cmd=( + docker + build + "$repo_root" + -f "$containerfile" + --tag "localhost/distribution-$DISTRO:dev" + --build-arg "DISTRO_NAME=$DISTRO" + --build-arg "INSTALL_MODE=editable" + --build-arg "LLAMA_STACK_DIR=/workspace" + ) + + if ! "${build_cmd[@]}"; then echo "❌ Failed to build Docker image" exit 1 fi @@ -224,7 +243,7 @@ start_container() { # Check if image exists (with or without localhost/ prefix) if ! docker images --format "{{.Repository}}:{{.Tag}}" | grep -q "distribution-$DISTRO:dev$"; then echo "❌ Error: Image distribution-$DISTRO:dev does not exist" - echo "Either build it first without --no-rebuild, or run: llama stack build --distro $DISTRO --image-type container" + echo "Either build it first without --no-rebuild, or run: docker build . -f containers/Containerfile --build-arg DISTRO_NAME=$DISTRO --tag localhost/distribution-$DISTRO:dev" exit 1 fi echo "✅ Found existing image for distribution-$DISTRO:dev" @@ -236,8 +255,10 @@ start_container() { echo "=== Starting Docker Container ===" # Get the repo root for volume mount - SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) - REPO_ROOT=$(cd "$SCRIPT_DIR/.." && pwd) + local script_dir + script_dir=$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd) + local repo_root + repo_root=$(cd "$script_dir/.." && pwd) # Determine the actual image name (may have localhost/ prefix) IMAGE_NAME=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep "distribution-$DISTRO:dev$" | head -1) @@ -279,10 +300,18 @@ start_container() { NETWORK_MODE="--network host" fi + local source_mount="" + if should_copy_source; then + echo "Source baked into image (no volume mount)" + else + source_mount="-v \"$repo_root\":/workspace" + echo "Mounting $repo_root into /workspace" + fi + docker run -d $NETWORK_MODE --name "$CONTAINER_NAME" \ -p $PORT:$PORT \ $DOCKER_ENV_VARS \ - -v "$REPO_ROOT":/app/llama-stack-source \ + $source_mount \ "$IMAGE_NAME" \ --port $PORT diff --git a/scripts/integration-tests.sh b/scripts/integration-tests.sh index e19a5cc55..93739052b 100755 --- a/scripts/integration-tests.sh +++ b/scripts/integration-tests.sh @@ -238,6 +238,8 @@ if [[ "$STACK_CONFIG" == *"docker:"* && "$COLLECT_ONLY" == false ]]; then echo "Stopping Docker container..." container_name="llama-stack-test-$DISTRO" if docker ps -a --format '{{.Names}}' | grep -q "^${container_name}$"; then + echo "Dumping container logs before stopping..." + docker logs "$container_name" > "docker-${DISTRO}-${INFERENCE_MODE}.log" 2>&1 || true echo "Stopping and removing container: $container_name" docker stop "$container_name" 2>/dev/null || true docker rm "$container_name" 2>/dev/null || true @@ -252,19 +254,24 @@ if [[ "$STACK_CONFIG" == *"docker:"* && "$COLLECT_ONLY" == false ]]; then export LLAMA_STACK_PORT=8321 echo "=== Building Docker Image for distribution: $DISTRO ===" - # Set LLAMA_STACK_DIR to repo root - # USE_COPY_NOT_MOUNT copies files into image (for CI), otherwise mounts for live development - BUILD_ENV="LLAMA_STACK_DIR=$ROOT_DIR" - if [[ "${CI:-false}" == "true" ]] || [[ "${GITHUB_ACTIONS:-false}" == "true" ]]; then - echo "CI detected (CI=$CI, GITHUB_ACTIONS=$GITHUB_ACTIONS): copying source into image" - BUILD_ENV="USE_COPY_NOT_MOUNT=true $BUILD_ENV" - else - echo "Local mode: will mount source for live development" + containerfile="$ROOT_DIR/containers/Containerfile" + if [[ ! -f "$containerfile" ]]; then + echo "❌ Containerfile not found at $containerfile" + exit 1 fi - eval "$BUILD_ENV llama stack build --distro '$DISTRO' --image-type container" + build_cmd=( + docker + build + "$ROOT_DIR" + -f "$containerfile" + --tag "localhost/distribution-$DISTRO:dev" + --build-arg "DISTRO_NAME=$DISTRO" + --build-arg "INSTALL_MODE=editable" + --build-arg "LLAMA_STACK_DIR=/workspace" + ) - if [ $? -ne 0 ]; then + if ! "${build_cmd[@]}"; then echo "❌ Failed to build Docker image" exit 1 fi @@ -304,7 +311,6 @@ if [[ "$STACK_CONFIG" == *"docker:"* && "$COLLECT_ONLY" == false ]]; then docker run -d --network host --name "$container_name" \ -p $LLAMA_STACK_PORT:$LLAMA_STACK_PORT \ $DOCKER_ENV_VARS \ - -v $ROOT_DIR:/app/llama-stack-source \ "$IMAGE_NAME" \ --port $LLAMA_STACK_PORT @@ -404,6 +410,21 @@ elif [ $exit_code -eq 5 ]; then echo "⚠️ No tests collected (pattern matched no tests)" else echo "❌ Tests failed" + echo "" + echo "=== Dumping last 100 lines of logs for debugging ===" + + # Output server or container logs based on stack config + if [[ "$STACK_CONFIG" == *"server:"* && -f "server.log" ]]; then + echo "--- Last 100 lines of server.log ---" + tail -100 server.log + elif [[ "$STACK_CONFIG" == *"docker:"* ]]; then + docker_log_file="docker-${DISTRO}-${INFERENCE_MODE}.log" + if [[ -f "$docker_log_file" ]]; then + echo "--- Last 100 lines of $docker_log_file ---" + tail -100 "$docker_log_file" + fi + fi + exit 1 fi diff --git a/tests/external/run-byoa.yaml b/tests/external/run-byoa.yaml index 5774ae9da..4d63046c6 100644 --- a/tests/external/run-byoa.yaml +++ b/tests/external/run-byoa.yaml @@ -7,6 +7,24 @@ providers: - provider_id: kaze provider_type: remote::kaze config: {} +storage: + backends: + kv_default: + type: kv_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/external}/kvstore.db + sql_default: + type: sql_sqlite + db_path: ${env.SQLITE_STORE_DIR:=~/.llama/distributions/external}/sql_store.db + stores: + metadata: + namespace: registry + backend: kv_default + inference: + table_name: inference_store + backend: sql_default + conversations: + table_name: openai_conversations + backend: sql_default external_apis_dir: ~/.llama/apis.d external_providers_dir: ~/.llama/providers.d server: diff --git a/tests/integration/agents/recordings/00f8a71ccb939737ed72a289eede62998c6882727519858bbd5954307d10a673.json b/tests/integration/agents/recordings/00f8a71ccb939737ed72a289eede62998c6882727519858bbd5954307d10a673.json index 4d4331740..067b7d254 100644 --- a/tests/integration/agents/recordings/00f8a71ccb939737ed72a289eede62998c6882727519858bbd5954307d10a673.json +++ b/tests/integration/agents/recordings/00f8a71ccb939737ed72a289eede62998c6882727519858bbd5954307d10a673.json @@ -548,5 +548,6 @@ } ], "is_streaming": true - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/0940d1521204120ff9687b8ad6bf54c271f879db8b5a6ce62848b86a43bc49e4.json b/tests/integration/agents/recordings/0940d1521204120ff9687b8ad6bf54c271f879db8b5a6ce62848b86a43bc49e4.json new file mode 100644 index 000000000..aa61b7dbe --- /dev/null +++ b/tests/integration/agents/recordings/0940d1521204120ff9687b8ad6bf54c271f879db8b5a6ce62848b86a43bc49e4.json @@ -0,0 +1,447 @@ +{ + "test_id": "tests/integration/agents/test_agents.py::test_tool_choice_get_boiling_point[ollama/llama3.2:3b-instruct-fp16]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama3.2:3b-instruct-fp16", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant" + }, + { + "role": "user", + "content": "What is the boiling point of the liquid polyjuice in celsius?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "id": "call_5qverjg6", + "type": "function", + "function": { + "name": "get_boiling_point", + "arguments": "{\"celcius\":true,\"liquid_name\":\"polyjuice\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_5qverjg6", + "content": "-100" + } + ], + "max_tokens": 512, + "stream": true, + "temperature": 0.0001, + "tool_choice": { + "type": "function", + "function": { + "name": "get_boiling_point" + } + }, + "tools": [ + { + "type": "function", + "function": { + "name": "get_boiling_point", + "description": "Returns the boiling point of a liquid in Celcius or Fahrenheit.", + "parameters": { + "type": "object", + "properties": { + "liquid_name": { + "type": "string", + "description": "The name of the liquid" + }, + "celcius": { + "type": "boolean", + "description": "Whether to return the boiling point in Celcius" + } + }, + "required": [ + "liquid_name" + ] + } + } + } + ], + "top_p": 0.9 + }, + "endpoint": "/v1/chat/completions", + "model": "llama3.2:3b-instruct-fp16" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": " boiling", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": " point", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": " liquid", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": " poly", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": "ju", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": "ice", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": " -", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": "100", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": "\u00b0C", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0940d1521204", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/0f5443c07d1568fd139b8f3ea0aaa3de23d22b30f353c8ed7e6cfd033d904e04.json b/tests/integration/agents/recordings/0f5443c07d1568fd139b8f3ea0aaa3de23d22b30f353c8ed7e6cfd033d904e04.json new file mode 100644 index 000000000..3cf297c34 --- /dev/null +++ b/tests/integration/agents/recordings/0f5443c07d1568fd139b8f3ea0aaa3de23d22b30f353c8ed7e6cfd033d904e04.json @@ -0,0 +1,888 @@ +{ + "test_id": "tests/integration/agents/test_openai_responses.py::test_response_with_instructions[txt=ollama/llama3.2:3b-instruct-fp16]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama3.2:3b-instruct-fp16", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant and speak in pirate language." + }, + { + "role": "user", + "content": "What is the capital of France?" + }, + { + "role": "assistant", + "content": "The capital of France is Paris." + } + ], + "stream": true, + "stream_options": { + "include_usage": true + } + }, + "endpoint": "/v1/chat/completions", + "model": "llama3.2:3b-instruct-fp16" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " Yer", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " look", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": "in", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": "'", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " fer", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " port", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " o", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": "'", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " call", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " eh", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": "?", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " That", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " be", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " one", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": "!", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " Yer", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " won", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": "'t", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " go", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " astr", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": "ay", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " with", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " that", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " answer", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": " mate", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": "y", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0f5443c07d15", + "choices": [], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": { + "completion_tokens": 32, + "prompt_tokens": 50, + "total_tokens": 82, + "completion_tokens_details": null, + "prompt_tokens_details": null + } + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/13fac3724cd626a119153f60fa56bb54955fe0b10f5c4102b78e2d428b5ffc7a.json b/tests/integration/agents/recordings/13fac3724cd626a119153f60fa56bb54955fe0b10f5c4102b78e2d428b5ffc7a.json index d606edb37..7efea91ba 100644 --- a/tests/integration/agents/recordings/13fac3724cd626a119153f60fa56bb54955fe0b10f5c4102b78e2d428b5ffc7a.json +++ b/tests/integration/agents/recordings/13fac3724cd626a119153f60fa56bb54955fe0b10f5c4102b78e2d428b5ffc7a.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/15b23045b5cdfc49228d58e4a082f8402f7c91d15e2240f855cc9b8b4e25352a.json b/tests/integration/agents/recordings/15b23045b5cdfc49228d58e4a082f8402f7c91d15e2240f855cc9b8b4e25352a.json new file mode 100644 index 000000000..b899e0c2d --- /dev/null +++ b/tests/integration/agents/recordings/15b23045b5cdfc49228d58e4a082f8402f7c91d15e2240f855cc9b8b4e25352a.json @@ -0,0 +1,256 @@ +{ + "test_id": "tests/integration/agents/test_openai_responses.py::test_response_with_instructions[txt=ollama/llama3.2:3b-instruct-fp16]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama3.2:3b-instruct-fp16", + "messages": [ + { + "role": "user", + "content": "What is the capital of France?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + } + }, + "endpoint": "/v1/chat/completions", + "model": "llama3.2:3b-instruct-fp16" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15b23045b5cd", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15b23045b5cd", + "choices": [ + { + "delta": { + "content": " capital", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15b23045b5cd", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15b23045b5cd", + "choices": [ + { + "delta": { + "content": " France", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15b23045b5cd", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15b23045b5cd", + "choices": [ + { + "delta": { + "content": " Paris", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15b23045b5cd", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15b23045b5cd", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15b23045b5cd", + "choices": [], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": { + "completion_tokens": 8, + "prompt_tokens": 32, + "total_tokens": 40, + "completion_tokens_details": null, + "prompt_tokens_details": null + } + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/1a0d3109cf92111ed4cb061a857dee0b99fa1e0b27934de1e6c5d29c03026626.json b/tests/integration/agents/recordings/1a0d3109cf92111ed4cb061a857dee0b99fa1e0b27934de1e6c5d29c03026626.json index b8b22f51d..407ac0655 100644 --- a/tests/integration/agents/recordings/1a0d3109cf92111ed4cb061a857dee0b99fa1e0b27934de1e6c5d29c03026626.json +++ b/tests/integration/agents/recordings/1a0d3109cf92111ed4cb061a857dee0b99fa1e0b27934de1e6c5d29c03026626.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/1adb6f4621eaa9e5d350925c3fc8c34fbb3d0af4cf4307d4363ff570c260287b.json b/tests/integration/agents/recordings/1adb6f4621eaa9e5d350925c3fc8c34fbb3d0af4cf4307d4363ff570c260287b.json index 4d7a1d1e4..241fb6127 100644 --- a/tests/integration/agents/recordings/1adb6f4621eaa9e5d350925c3fc8c34fbb3d0af4cf4307d4363ff570c260287b.json +++ b/tests/integration/agents/recordings/1adb6f4621eaa9e5d350925c3fc8c34fbb3d0af4cf4307d4363ff570c260287b.json @@ -55,7 +55,7 @@ "choices": [ { "delta": { - "content": "'m", + "content": "'d", "function_call": null, "refusal": null, "role": "assistant", @@ -81,7 +81,7 @@ "choices": [ { "delta": { - "content": " not", + "content": " be", "function_call": null, "refusal": null, "role": "assistant", @@ -107,7 +107,7 @@ "choices": [ { "delta": { - "content": " able", + "content": " happy", "function_call": null, "refusal": null, "role": "assistant", @@ -159,7 +159,7 @@ "choices": [ { "delta": { - "content": " provide", + "content": " help", "function_call": null, "refusal": null, "role": "assistant", @@ -185,7 +185,7 @@ "choices": [ { "delta": { - "content": " real", + "content": " you", "function_call": null, "refusal": null, "role": "assistant", @@ -211,7 +211,59 @@ "choices": [ { "delta": { - "content": "-time", + "content": " with", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " current", "function_call": null, "refusal": null, "role": "assistant", @@ -282,6 +334,58 @@ "usage": null } }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " Tokyo", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, { "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", "__data__": { @@ -393,189 +497,7 @@ "choices": [ { "delta": { - "content": " can", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " tell", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " you", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " that", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " Tokyo", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": ",", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " Japan", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " has", + "content": "'m", "function_call": null, "refusal": null, "role": "assistant", @@ -627,7 +549,7 @@ "choices": [ { "delta": { - "content": " humid", + "content": " large", "function_call": null, "refusal": null, "role": "assistant", @@ -653,7 +575,7 @@ "choices": [ { "delta": { - "content": " subt", + "content": " language", "function_call": null, "refusal": null, "role": "assistant", @@ -679,7 +601,7 @@ "choices": [ { "delta": { - "content": "ropical", + "content": " model", "function_call": null, "refusal": null, "role": "assistant", @@ -705,7 +627,7 @@ "choices": [ { "delta": { - "content": " climate", + "content": ",", "function_call": null, "refusal": null, "role": "assistant", @@ -731,7 +653,7 @@ "choices": [ { "delta": { - "content": " with", + "content": " I", "function_call": null, "refusal": null, "role": "assistant", @@ -757,7 +679,7 @@ "choices": [ { "delta": { - "content": " hot", + "content": " don", "function_call": null, "refusal": null, "role": "assistant", @@ -783,7 +705,7 @@ "choices": [ { "delta": { - "content": " summers", + "content": "'t", "function_call": null, "refusal": null, "role": "assistant", @@ -809,7 +731,7 @@ "choices": [ { "delta": { - "content": " and", + "content": " have", "function_call": null, "refusal": null, "role": "assistant", @@ -835,7 +757,7 @@ "choices": [ { "delta": { - "content": " cold", + "content": " real", "function_call": null, "refusal": null, "role": "assistant", @@ -861,7 +783,7 @@ "choices": [ { "delta": { - "content": " winters", + "content": "-time", "function_call": null, "refusal": null, "role": "assistant", @@ -887,111 +809,7 @@ "choices": [ { "delta": { - "content": ".\n\n", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": "If", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " you", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": "'d", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " like", + "content": " access", "function_call": null, "refusal": null, "role": "assistant", @@ -1043,7 +861,449 @@ "choices": [ { "delta": { - "content": " know", + "content": " current", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " weather", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " conditions", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ".\n\n", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": "That", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " being", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " said", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " I", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " can", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " suggest", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " some", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " ways", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " to", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " find", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " out", "function_call": null, "refusal": null, "role": "assistant", @@ -1147,59 +1407,7 @@ "choices": [ { "delta": { - "content": " or", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " forecast", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " for", + "content": " in", "function_call": null, "refusal": null, "role": "assistant", @@ -1251,7 +1459,7 @@ "choices": [ { "delta": { - "content": ",", + "content": ":\n\n", "function_call": null, "refusal": null, "role": "assistant", @@ -1277,7 +1485,7 @@ "choices": [ { "delta": { - "content": " I", + "content": "1", "function_call": null, "refusal": null, "role": "assistant", @@ -1303,7 +1511,7 @@ "choices": [ { "delta": { - "content": " recommend", + "content": ".", "function_call": null, "refusal": null, "role": "assistant", @@ -1329,59 +1537,7 @@ "choices": [ { "delta": { - "content": " checking", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " a", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " reliable", + "content": " Check", "function_call": null, "refusal": null, "role": "assistant", @@ -1433,7 +1589,7 @@ "choices": [ { "delta": { - "content": " source", + "content": " weather", "function_call": null, "refusal": null, "role": "assistant", @@ -1459,7 +1615,7 @@ "choices": [ { "delta": { - "content": " such", + "content": " websites", "function_call": null, "refusal": null, "role": "assistant", @@ -1485,7 +1641,7 @@ "choices": [ { "delta": { - "content": " as", + "content": ":", "function_call": null, "refusal": null, "role": "assistant", @@ -1511,7 +1667,7 @@ "choices": [ { "delta": { - "content": ":\n\n", + "content": " You", "function_call": null, "refusal": null, "role": "assistant", @@ -1537,7 +1693,7 @@ "choices": [ { "delta": { - "content": "*", + "content": " can", "function_call": null, "refusal": null, "role": "assistant", @@ -1563,7 +1719,267 @@ "choices": [ { "delta": { - "content": " The", + "content": " check", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " websites", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " like", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " Acc", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": "u", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": "Weather", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " Weather", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ".com", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " or", "function_call": null, "refusal": null, "role": "assistant", @@ -1797,7 +2213,397 @@ "choices": [ { "delta": { - "content": " website", + "content": " for", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " current", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " weather", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " condition", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " and", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " forecast", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " Tokyo", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ".\n", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": "2", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " Use", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " mobile", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " app", "function_call": null, "refusal": null, "role": "assistant", @@ -1849,7 +2655,7 @@ "choices": [ { "delta": { - "content": " \n", + "content": " provide", "function_call": null, "refusal": null, "role": "assistant", @@ -2057,7 +2863,7 @@ "choices": [ { "delta": { - "content": "*", + "content": " real", "function_call": null, "refusal": null, "role": "assistant", @@ -2083,7 +2889,7 @@ "choices": [ { "delta": { - "content": " Acc", + "content": "-time", "function_call": null, "refusal": null, "role": "assistant", @@ -2109,7 +2915,7 @@ "choices": [ { "delta": { - "content": "u", + "content": " weather", "function_call": null, "refusal": null, "role": "assistant", @@ -2135,7 +2941,7 @@ "choices": [ { "delta": { - "content": "Weather", + "content": " information", "function_call": null, "refusal": null, "role": "assistant", @@ -2161,7 +2967,7 @@ "choices": [ { "delta": { - "content": ":", + "content": ",", "function_call": null, "refusal": null, "role": "assistant", @@ -2187,7 +2993,7 @@ "choices": [ { "delta": { - "content": " https", + "content": " such", "function_call": null, "refusal": null, "role": "assistant", @@ -2213,189 +3019,7 @@ "choices": [ { "delta": { - "content": "://", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": "www", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": ".acc", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": "u", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": "weather", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": ".com", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": "/\n", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": "*", + "content": " as", "function_call": null, "refusal": null, "role": "assistant", @@ -2466,6 +3090,240 @@ "usage": null } }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " or", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " Weather", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " Underground", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ".\n", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " Check", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " social", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " media", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, { "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", "__data__": { @@ -2499,7 +3357,7 @@ "choices": [ { "delta": { - "content": " https", + "content": " You", "function_call": null, "refusal": null, "role": "assistant", @@ -2525,7 +3383,7 @@ "choices": [ { "delta": { - "content": "://", + "content": " can", "function_call": null, "refusal": null, "role": "assistant", @@ -2551,7 +3409,7 @@ "choices": [ { "delta": { - "content": "dark", + "content": " also", "function_call": null, "refusal": null, "role": "assistant", @@ -2577,7 +3435,7 @@ "choices": [ { "delta": { - "content": "sky", + "content": " check", "function_call": null, "refusal": null, "role": "assistant", @@ -2603,7 +3461,7 @@ "choices": [ { "delta": { - "content": ".net", + "content": " social", "function_call": null, "refusal": null, "role": "assistant", @@ -2629,7 +3487,7 @@ "choices": [ { "delta": { - "content": "/\n\n", + "content": " media", "function_call": null, "refusal": null, "role": "assistant", @@ -2655,7 +3513,7 @@ "choices": [ { "delta": { - "content": "Please", + "content": " platforms", "function_call": null, "refusal": null, "role": "assistant", @@ -2681,7 +3539,215 @@ "choices": [ { "delta": { - "content": " keep", + "content": " like", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " Twitter", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " or", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " Facebook", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " updates", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " on", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " weather", "function_call": null, "refusal": null, "role": "assistant", @@ -2733,7 +3799,85 @@ "choices": [ { "delta": { - "content": " mind", + "content": " Tokyo", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ".\n\n", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": "Please", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " note", "function_call": null, "refusal": null, "role": "assistant", @@ -2778,6 +3922,578 @@ "usage": null } }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " my", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " knowledge", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " cutoff", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " December", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " so", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " I", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " may", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " not", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " have", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " most", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " up", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": "-to", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": "-date", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " information", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " on", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1adb6f4621ea", + "choices": [ + { + "delta": { + "content": " current", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, { "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", "__data__": { @@ -2830,526 +4546,6 @@ "usage": null } }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " can", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " change", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " quickly", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": ",", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " and", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " it", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": "'s", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " always", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " a", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " good", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " idea", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " to", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " check", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " the", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " latest", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " forecast", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " before", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " planning", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " your", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-1adb6f4621ea", - "choices": [ - { - "delta": { - "content": " activities", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, { "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", "__data__": { @@ -3413,9 +4609,9 @@ "service_tier": null, "system_fingerprint": "fp_ollama", "usage": { - "completion_tokens": 131, + "completion_tokens": 176, "prompt_tokens": 32, - "total_tokens": 163, + "total_tokens": 208, "completion_tokens_details": null, "prompt_tokens_details": null } diff --git a/tests/integration/agents/recordings/1f0aef7475448c77021b4e321125b4df3aadc1637a93358a85c5ec2de8338332.json b/tests/integration/agents/recordings/1f0aef7475448c77021b4e321125b4df3aadc1637a93358a85c5ec2de8338332.json new file mode 100644 index 000000000..4c0fa6cce --- /dev/null +++ b/tests/integration/agents/recordings/1f0aef7475448c77021b4e321125b4df3aadc1637a93358a85c5ec2de8338332.json @@ -0,0 +1,442 @@ +{ + "test_id": "tests/integration/agents/test_agents.py::test_create_turn_response[ollama/llama3.2:3b-instruct-fp16-client_tools1]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama3.2:3b-instruct-fp16", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant" + }, + { + "role": "user", + "content": "Call get_boiling_point_with_metadata tool and answer What is the boiling point of polyjuice?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "id": "call_klhbln13", + "type": "function", + "function": { + "name": "get_boiling_point_with_metadata", + "arguments": "{\"celcius\":false,\"liquid_name\":\"polyjuice\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_klhbln13", + "content": "-212" + } + ], + "max_tokens": 512, + "stream": true, + "temperature": 0.0001, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_boiling_point_with_metadata", + "description": "Returns the boiling point of a liquid in Celcius or Fahrenheit", + "parameters": { + "type": "object", + "properties": { + "liquid_name": { + "type": "string", + "description": "The name of the liquid" + }, + "celcius": { + "type": "boolean", + "description": "Whether to return the boiling point in Celcius" + } + }, + "required": [ + "liquid_name" + ] + } + } + } + ], + "top_p": 0.9 + }, + "endpoint": "/v1/chat/completions", + "model": "llama3.2:3b-instruct-fp16" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": " boiling", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": " point", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": " poly", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": "ju", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": "ice", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": " -", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": "212", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": " degrees", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": " Celsius", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1f0aef747544", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/2172059863d4d17e7525483102a6753617b60a8c33ece637db18061d23086536.json b/tests/integration/agents/recordings/2172059863d4d17e7525483102a6753617b60a8c33ece637db18061d23086536.json index 992648658..9f9397057 100644 --- a/tests/integration/agents/recordings/2172059863d4d17e7525483102a6753617b60a8c33ece637db18061d23086536.json +++ b/tests/integration/agents/recordings/2172059863d4d17e7525483102a6753617b60a8c33ece637db18061d23086536.json @@ -56,7 +56,7 @@ "tool_calls": [ { "index": 0, - "id": "call_os3xa9go", + "id": "call_6nqo069h", "function": { "arguments": "{\"city\":\"Tokyo\"}", "name": "get_weather" @@ -115,9 +115,9 @@ "service_tier": null, "system_fingerprint": "fp_ollama", "usage": { - "completion_tokens": 15, + "completion_tokens": 18, "prompt_tokens": 179, - "total_tokens": 194, + "total_tokens": 197, "completion_tokens_details": null, "prompt_tokens_details": null } diff --git a/tests/integration/agents/recordings/256d8571909664fc6c925058b2ff1b1d0e0bd618975cbf4752eb31ada6d2482b.json b/tests/integration/agents/recordings/256d8571909664fc6c925058b2ff1b1d0e0bd618975cbf4752eb31ada6d2482b.json new file mode 100644 index 000000000..21d5a0663 --- /dev/null +++ b/tests/integration/agents/recordings/256d8571909664fc6c925058b2ff1b1d0e0bd618975cbf4752eb31ada6d2482b.json @@ -0,0 +1,416 @@ +{ + "test_id": "tests/integration/agents/test_agents.py::test_custom_tool_infinite_loop[ollama/llama3.2:3b-instruct-fp16]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama3.2:3b-instruct-fp16", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant Always respond with tool calls no matter what. " + }, + { + "role": "user", + "content": "Get the boiling point of polyjuice with a tool call." + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "id": "call_9x4z21g1", + "type": "function", + "function": { + "name": "get_boiling_point", + "arguments": "{\"celcius\":\"true\",\"liquid_name\":\"polyjuice\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_9x4z21g1", + "content": "-100" + } + ], + "max_tokens": 512, + "stream": true, + "temperature": 0.0001, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_boiling_point", + "description": "Returns the boiling point of a liquid in Celcius or Fahrenheit.", + "parameters": { + "type": "object", + "properties": { + "liquid_name": { + "type": "string", + "description": "The name of the liquid" + }, + "celcius": { + "type": "boolean", + "description": "Whether to return the boiling point in Celcius" + } + }, + "required": [ + "liquid_name" + ] + } + } + } + ], + "top_p": 0.9 + }, + "endpoint": "/v1/chat/completions", + "model": "llama3.2:3b-instruct-fp16" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": " boiling", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": " point", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": " Poly", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": "ju", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": "ice", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": " -", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": "100", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": "\u00b0C", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-256d85719096", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/292308724331c7172aaf91fe1373f2fbc9d626af08314bd7f5ba69d038ea7c1b.json b/tests/integration/agents/recordings/292308724331c7172aaf91fe1373f2fbc9d626af08314bd7f5ba69d038ea7c1b.json index a94c52c72..9a1781046 100644 --- a/tests/integration/agents/recordings/292308724331c7172aaf91fe1373f2fbc9d626af08314bd7f5ba69d038ea7c1b.json +++ b/tests/integration/agents/recordings/292308724331c7172aaf91fe1373f2fbc9d626af08314bd7f5ba69d038ea7c1b.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/36e22908b34c0835037ba7b52477c5db69585e66f4fde18eaa8bfd4bb4e3d783.json b/tests/integration/agents/recordings/36e22908b34c0835037ba7b52477c5db69585e66f4fde18eaa8bfd4bb4e3d783.json index 3699fbc8b..3a1f57ee8 100644 --- a/tests/integration/agents/recordings/36e22908b34c0835037ba7b52477c5db69585e66f4fde18eaa8bfd4bb4e3d783.json +++ b/tests/integration/agents/recordings/36e22908b34c0835037ba7b52477c5db69585e66f4fde18eaa8bfd4bb4e3d783.json @@ -66,7 +66,7 @@ "tool_calls": [ { "index": 0, - "id": "call_ixvkq8fh", + "id": "call_icfpgg5q", "function": { "arguments": "{\"celcius\":true,\"liquid_name\":\"polyjuice\"}", "name": "get_boiling_point" @@ -116,5 +116,6 @@ } ], "is_streaming": true - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/45175e711385e24f62516c3982eaf8fb6bbab4f37691fadc08812ce223dfc628.json b/tests/integration/agents/recordings/45175e711385e24f62516c3982eaf8fb6bbab4f37691fadc08812ce223dfc628.json index 4f001f5bf..0a27ddb7d 100644 --- a/tests/integration/agents/recordings/45175e711385e24f62516c3982eaf8fb6bbab4f37691fadc08812ce223dfc628.json +++ b/tests/integration/agents/recordings/45175e711385e24f62516c3982eaf8fb6bbab4f37691fadc08812ce223dfc628.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/45d0aabc502385b4cc23e16706a1c594644b2a1387ac3cee7cd434df25e8f22f.json b/tests/integration/agents/recordings/45d0aabc502385b4cc23e16706a1c594644b2a1387ac3cee7cd434df25e8f22f.json new file mode 100644 index 000000000..bfbbcb87b --- /dev/null +++ b/tests/integration/agents/recordings/45d0aabc502385b4cc23e16706a1c594644b2a1387ac3cee7cd434df25e8f22f.json @@ -0,0 +1,442 @@ +{ + "test_id": "tests/integration/agents/test_agents.py::test_custom_tool[ollama/llama3.2:3b-instruct-fp16]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama3.2:3b-instruct-fp16", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant" + }, + { + "role": "user", + "content": "What is the boiling point of the liquid polyjuice in celsius?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "id": "call_icfpgg5q", + "type": "function", + "function": { + "name": "get_boiling_point", + "arguments": "{\"celcius\":true,\"liquid_name\":\"polyjuice\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_icfpgg5q", + "content": "-100" + } + ], + "max_tokens": 512, + "stream": true, + "temperature": 0.0001, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_boiling_point", + "description": "Returns the boiling point of a liquid in Celcius or Fahrenheit.", + "parameters": { + "type": "object", + "properties": { + "liquid_name": { + "type": "string", + "description": "The name of the liquid" + }, + "celcius": { + "type": "boolean", + "description": "Whether to return the boiling point in Celcius" + } + }, + "required": [ + "liquid_name" + ] + } + } + } + ], + "top_p": 0.9 + }, + "endpoint": "/v1/chat/completions", + "model": "llama3.2:3b-instruct-fp16" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": " boiling", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": " point", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": " liquid", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": " poly", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": "ju", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": "ice", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": " -", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": "100", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": "\u00b0C", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-45d0aabc5023", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/4da32cdf48ae4c3b381e3557edb99afa0ff16a609aaa941737e99606961a6a07.json b/tests/integration/agents/recordings/4da32cdf48ae4c3b381e3557edb99afa0ff16a609aaa941737e99606961a6a07.json index 89fa490c3..755276918 100644 --- a/tests/integration/agents/recordings/4da32cdf48ae4c3b381e3557edb99afa0ff16a609aaa941737e99606961a6a07.json +++ b/tests/integration/agents/recordings/4da32cdf48ae4c3b381e3557edb99afa0ff16a609aaa941737e99606961a6a07.json @@ -45,7 +45,33 @@ "choices": [ { "delta": { - "content": "The", + "content": "Italy", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": "'s", "function_call": null, "refusal": null, "role": "assistant", @@ -90,58 +116,6 @@ "usage": null } }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-4da32cdf48ae", - "choices": [ - { - "delta": { - "content": " of", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-4da32cdf48ae", - "choices": [ - { - "delta": { - "content": " Italy", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, { "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", "__data__": { @@ -194,6 +168,1124 @@ "usage": null } }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " and", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " also", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " seat", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " EU", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " as", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " well", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " it", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " has", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " been", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " centuries", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " significant", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " role", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " international", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " politics", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " with", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " that", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " being", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " also", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " an", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " important", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " location", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " various", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " historical", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " events", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " such", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " like", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " signing", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " treaty", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": " West", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": "ph", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-4da32cdf48ae", + "choices": [ + { + "delta": { + "content": "alia", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, { "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", "__data__": { @@ -257,9 +1349,9 @@ "service_tier": null, "system_fingerprint": "fp_ollama", "usage": { - "completion_tokens": 8, + "completion_tokens": 50, "prompt_tokens": 82, - "total_tokens": 90, + "total_tokens": 132, "completion_tokens_details": null, "prompt_tokens_details": null } diff --git a/tests/integration/agents/recordings/585a2cf2c22b0db155a6a94052836b34c42f68bf04b1b2cb74ddf00943c0442d.json b/tests/integration/agents/recordings/585a2cf2c22b0db155a6a94052836b34c42f68bf04b1b2cb74ddf00943c0442d.json index cac9a6db2..988b270d7 100644 --- a/tests/integration/agents/recordings/585a2cf2c22b0db155a6a94052836b34c42f68bf04b1b2cb74ddf00943c0442d.json +++ b/tests/integration/agents/recordings/585a2cf2c22b0db155a6a94052836b34c42f68bf04b1b2cb74ddf00943c0442d.json @@ -48,7 +48,7 @@ "tool_calls": [ { "index": 0, - "id": "call_lqrdy0rt", + "id": "call_x427af31", "function": { "arguments": "{}", "name": "get_current_time" @@ -107,9 +107,9 @@ "service_tier": null, "system_fingerprint": "fp_ollama", "usage": { - "completion_tokens": 14, + "completion_tokens": 12, "prompt_tokens": 161, - "total_tokens": 175, + "total_tokens": 173, "completion_tokens_details": null, "prompt_tokens_details": null } diff --git a/tests/integration/agents/recordings/5edf2f0b7a9c875e80e4719f71a1daa94c1287acf164cd81ddd51843d05be718.json b/tests/integration/agents/recordings/5edf2f0b7a9c875e80e4719f71a1daa94c1287acf164cd81ddd51843d05be718.json index 49ca098d5..009646e27 100644 --- a/tests/integration/agents/recordings/5edf2f0b7a9c875e80e4719f71a1daa94c1287acf164cd81ddd51843d05be718.json +++ b/tests/integration/agents/recordings/5edf2f0b7a9c875e80e4719f71a1daa94c1287acf164cd81ddd51843d05be718.json @@ -56,7 +56,7 @@ "tool_calls": [ { "index": 0, - "id": "call_4ibtjudr", + "id": "call_wkjhgmpf", "function": { "arguments": "{\"city\":\"Tokyo\"}", "name": "get_weather" diff --git a/tests/integration/agents/recordings/697a25dd7f0ff515f567c883ad72ae9dca423726834aec8b38420dccb735c050.json b/tests/integration/agents/recordings/697a25dd7f0ff515f567c883ad72ae9dca423726834aec8b38420dccb735c050.json index 298e0e3b8..8b8f04ae6 100644 --- a/tests/integration/agents/recordings/697a25dd7f0ff515f567c883ad72ae9dca423726834aec8b38420dccb735c050.json +++ b/tests/integration/agents/recordings/697a25dd7f0ff515f567c883ad72ae9dca423726834aec8b38420dccb735c050.json @@ -66,7 +66,7 @@ "tool_calls": [ { "index": 0, - "id": "call_pojpzwm8", + "id": "call_klhbln13", "function": { "arguments": "{\"celcius\":false,\"liquid_name\":\"polyjuice\"}", "name": "get_boiling_point_with_metadata" @@ -116,5 +116,6 @@ } ], "is_streaming": true - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/6b207540bc67e2b9e6beb091d477d446d91e9837add7e9f4de236627195d41e4.json b/tests/integration/agents/recordings/6b207540bc67e2b9e6beb091d477d446d91e9837add7e9f4de236627195d41e4.json index fc263d5e9..d5d249587 100644 --- a/tests/integration/agents/recordings/6b207540bc67e2b9e6beb091d477d446d91e9837add7e9f4de236627195d41e4.json +++ b/tests/integration/agents/recordings/6b207540bc67e2b9e6beb091d477d446d91e9837add7e9f4de236627195d41e4.json @@ -81,33 +81,7 @@ "choices": [ { "delta": { - "content": " not", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " able", + "content": " happy", "function_call": null, "refusal": null, "role": "assistant", @@ -159,267 +133,7 @@ "choices": [ { "delta": { - "content": " provide", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " real", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "-time", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " weather", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " information", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ".", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " However", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ",", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " I", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " can", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " give", + "content": " help", "function_call": null, "refusal": null, "role": "assistant", @@ -471,7 +185,7 @@ "choices": [ { "delta": { - "content": " an", + "content": " with", "function_call": null, "refusal": null, "role": "assistant", @@ -497,7 +211,7 @@ "choices": [ { "delta": { - "content": " idea", + "content": " your", "function_call": null, "refusal": null, "role": "assistant", @@ -523,553 +237,7 @@ "choices": [ { "delta": { - "content": " of", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " what", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " Tokyo", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "'s", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " typical", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " weather", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " is", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " like", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " during", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " different", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " seasons", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ".\n\n", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "**", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "Spring", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " (", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "March", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " to", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " May", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ")**", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ":", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " Mild", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " temperatures", + "content": " question", "function_call": null, "refusal": null, "role": "assistant", @@ -1121,7 +289,7 @@ "choices": [ { "delta": { - "content": " usually", + "content": " but", "function_call": null, "refusal": null, "role": "assistant", @@ -1147,7 +315,85 @@ "choices": [ { "delta": { - "content": " ranging", + "content": " I", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " need", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " more", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " information", "function_call": null, "refusal": null, "role": "assistant", @@ -1199,7 +445,7 @@ "choices": [ { "delta": { - "content": " ", + "content": " you", "function_call": null, "refusal": null, "role": "assistant", @@ -1225,7 +471,7 @@ "choices": [ { "delta": { - "content": "10", + "content": ".", "function_call": null, "refusal": null, "role": "assistant", @@ -1251,3725 +497,7 @@ "choices": [ { "delta": { - "content": "\u00b0C", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " to", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " ", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "20", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0C", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " (", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "50", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0F", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " to", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " ", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "68", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0F", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ").", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " It", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "'s", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " a", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " great", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " time", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " to", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " visit", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " Tokyo", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " for", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " cherry", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " blossom", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " season", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ".\n\n", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "**", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "Summer", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " (", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "June", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " to", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " August", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ")**", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ":", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " Hot", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " and", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " humid", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ",", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " with", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " temperatures", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " often", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " exceeding", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " ", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "30", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0C", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " (", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "86", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0F", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ").", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " Summer", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " is", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " rainy", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ",", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " with", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " heavy", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " down", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "p", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "ours", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " during", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " the", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " after", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "no", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "ons", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ".\n\n", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "**", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "Aut", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "umn", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " (", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "September", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " to", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " November", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ")**", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ":", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " Comfort", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "able", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " temperatures", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ",", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " ranging", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " from", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " ", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "10", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0C", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " to", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " ", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "20", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0C", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " (", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "50", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0F", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " to", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " ", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "68", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0F", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ").", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " Autumn", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " foliage", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " is", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " a", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " highlight", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " of", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " Tokyo", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "'s", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " scenery", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ".\n\n", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "**", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "Winter", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " (", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "December", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " to", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " February", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ")**", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ":", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " Cold", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " and", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " snowy", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ",", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " with", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " temperatures", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " sometimes", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " dropping", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " below", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " ", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "0", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0C", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " (", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "32", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "\u00b0F", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ").", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " Snow", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "fall", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " can", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " be", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " significant", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " in", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " some", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " parts", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " of", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " the", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " city", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": ".\n\n", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": "Please", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " note", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " that", - "function_call": null, - "refusal": null, - "role": "assistant", - "tool_calls": null - }, - "finish_reason": null, - "index": 0, - "logprobs": null - } - ], - "created": 0, - "model": "llama3.2:3b-instruct-fp16", - "object": "chat.completion.chunk", - "service_tier": null, - "system_fingerprint": "fp_ollama", - "usage": null - } - }, - { - "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", - "__data__": { - "id": "rec-6b207540bc67", - "choices": [ - { - "delta": { - "content": " these", + "content": " There", "function_call": null, "refusal": null, "role": "assistant", @@ -5021,7 +549,7 @@ "choices": [ { "delta": { - "content": " general", + "content": " many", "function_call": null, "refusal": null, "role": "assistant", @@ -5047,7 +575,7 @@ "choices": [ { "delta": { - "content": " temperature", + "content": " cities", "function_call": null, "refusal": null, "role": "assistant", @@ -5073,7 +601,33 @@ "choices": [ { "delta": { - "content": " ranges", + "content": " named", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " Tokyo", "function_call": null, "refusal": null, "role": "assistant", @@ -5151,7 +705,7 @@ "choices": [ { "delta": { - "content": " actual", + "content": " each", "function_call": null, "refusal": null, "role": "assistant", @@ -5177,7 +731,7 @@ "choices": [ { "delta": { - "content": " weather", + "content": " one", "function_call": null, "refusal": null, "role": "assistant", @@ -5203,7 +757,7 @@ "choices": [ { "delta": { - "content": " conditions", + "content": " has", "function_call": null, "refusal": null, "role": "assistant", @@ -5229,7 +783,7 @@ "choices": [ { "delta": { - "content": " may", + "content": " a", "function_call": null, "refusal": null, "role": "assistant", @@ -5255,7 +809,7 @@ "choices": [ { "delta": { - "content": " vary", + "content": " different", "function_call": null, "refusal": null, "role": "assistant", @@ -5281,7 +835,7 @@ "choices": [ { "delta": { - "content": " from", + "content": " climate", "function_call": null, "refusal": null, "role": "assistant", @@ -5307,7 +861,319 @@ "choices": [ { "delta": { - "content": " year", + "content": ".\n\n", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": "Could", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " please", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " tell", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " me", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " which", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " city", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " Japan", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " are", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " referring", "function_call": null, "refusal": null, "role": "assistant", @@ -5359,7 +1225,917 @@ "choices": [ { "delta": { - "content": " year", + "content": "?", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " Tokyo", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " itself", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " not", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " always", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " good", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " choice", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " as", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " it", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " often", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " gets", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " confused", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " with", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " actual", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " name", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " large", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " and", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " populous", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " area", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " K", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": "anto", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " which", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " includes", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " larger", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " areas", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " surrounding", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " Tokyo", "function_call": null, "refusal": null, "role": "assistant", @@ -5404,6 +2180,708 @@ "usage": null } }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " \n\n", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": "If", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " that", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " does", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " not", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " give", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " us", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " enough", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " grounds", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " then", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " could", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " provide", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " also", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " what", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " approximate", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " month", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " want", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " information", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " about", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " (", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": "for", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " seasonal", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": " changes", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-6b207540bc67", + "choices": [ + { + "delta": { + "content": ")?", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, { "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", "__data__": { @@ -5441,9 +2919,9 @@ "service_tier": null, "system_fingerprint": "fp_ollama", "usage": { - "completion_tokens": 208, + "completion_tokens": 111, "prompt_tokens": 32, - "total_tokens": 240, + "total_tokens": 143, "completion_tokens_details": null, "prompt_tokens_details": null } diff --git a/tests/integration/agents/recordings/6da760645fe224ace4ab628e4f647259897598e28037fe5f7c09f6677edd08e9.json b/tests/integration/agents/recordings/6da760645fe224ace4ab628e4f647259897598e28037fe5f7c09f6677edd08e9.json index 41c4f97ae..a178476e1 100644 --- a/tests/integration/agents/recordings/6da760645fe224ace4ab628e4f647259897598e28037fe5f7c09f6677edd08e9.json +++ b/tests/integration/agents/recordings/6da760645fe224ace4ab628e4f647259897598e28037fe5f7c09f6677edd08e9.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/7094319e038424fbec54338c397b487c7128fc28534351deb4662fba31043fa4.json b/tests/integration/agents/recordings/7094319e038424fbec54338c397b487c7128fc28534351deb4662fba31043fa4.json index dce0c2e4d..7f7bf13ca 100644 --- a/tests/integration/agents/recordings/7094319e038424fbec54338c397b487c7128fc28534351deb4662fba31043fa4.json +++ b/tests/integration/agents/recordings/7094319e038424fbec54338c397b487c7128fc28534351deb4662fba31043fa4.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/74c26f63592ceedb76eb9623fce41773965dd66b569506b5622b1a797c45f8e4.json b/tests/integration/agents/recordings/74c26f63592ceedb76eb9623fce41773965dd66b569506b5622b1a797c45f8e4.json index d8b125dad..a1464e8c3 100644 --- a/tests/integration/agents/recordings/74c26f63592ceedb76eb9623fce41773965dd66b569506b5622b1a797c45f8e4.json +++ b/tests/integration/agents/recordings/74c26f63592ceedb76eb9623fce41773965dd66b569506b5622b1a797c45f8e4.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/7e0d8c4abe407611ceaa99beea2e9973e2a938cab3db3e1be017bbe8be10edc6.json b/tests/integration/agents/recordings/7e0d8c4abe407611ceaa99beea2e9973e2a938cab3db3e1be017bbe8be10edc6.json index e11d38095..665e53245 100644 --- a/tests/integration/agents/recordings/7e0d8c4abe407611ceaa99beea2e9973e2a938cab3db3e1be017bbe8be10edc6.json +++ b/tests/integration/agents/recordings/7e0d8c4abe407611ceaa99beea2e9973e2a938cab3db3e1be017bbe8be10edc6.json @@ -66,7 +66,7 @@ "tool_calls": [ { "index": 0, - "id": "call_rwasjr3y", + "id": "call_zqu5i0ti", "function": { "arguments": "{\"celcius\":null,\"liquid_name\":\"polyjuice\"}", "name": "get_boiling_point" @@ -116,5 +116,6 @@ } ], "is_streaming": true - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/7e794c73bf79604a10482bba03124849cb763c7bb66acf3937b524a539b80366.json b/tests/integration/agents/recordings/7e794c73bf79604a10482bba03124849cb763c7bb66acf3937b524a539b80366.json new file mode 100644 index 000000000..dfae71291 --- /dev/null +++ b/tests/integration/agents/recordings/7e794c73bf79604a10482bba03124849cb763c7bb66acf3937b524a539b80366.json @@ -0,0 +1,59 @@ +{ + "test_id": "tests/integration/agents/test_agents.py::test_tool_choice_required[ollama/llama3.2:3b-instruct-fp16]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama-guard3:1b", + "messages": [ + { + "role": "user", + "content": "Task: Check if there is unsafe content in 'Assistant' messages in conversations according our safety policy with the below categories.\n\n\nS1: Violent Crimes.\nS2: Non-Violent Crimes.\nS3: Sex Crimes.\nS4: Child Exploitation.\nS5: Defamation.\nS6: Specialized Advice.\nS7: Privacy.\nS8: Intellectual Property.\nS9: Indiscriminate Weapons.\nS10: Hate.\nS11: Self-Harm.\nS12: Sexual Content.\nS13: Elections.\nS14: Code Interpreter Abuse.\n\n\n\n\nUser: What is the boiling point of the liquid polyjuice in celsius?\n\nAssistant: \n\nTool: -100\n\nAssistant: The boiling point of liquid polyjuice is -100\u00b0C.\n\n\n\nProvide your safety assessment for ONLY THE LAST Assistant message in the above conversation:\n - First line must read 'safe' or 'unsafe'.\n - If unsafe, a second line must include a comma-separated list of violated categories." + } + ], + "stream": false, + "temperature": 0.0 + }, + "endpoint": "/v1/chat/completions", + "model": "llama-guard3:1b" + }, + "response": { + "body": { + "__type__": "openai.types.chat.chat_completion.ChatCompletion", + "__data__": { + "id": "rec-7e794c73bf79", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "logprobs": null, + "message": { + "content": "safe", + "refusal": null, + "role": "assistant", + "annotations": null, + "audio": null, + "function_call": null, + "tool_calls": null + } + } + ], + "created": 0, + "model": "llama-guard3:1b", + "object": "chat.completion", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 421, + "total_tokens": 423, + "completion_tokens_details": null, + "prompt_tokens_details": null + } + } + }, + "is_streaming": false + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/868820c8d798c0d16063d1750a65ae2632ecf543ee440e7d87ea16f8e83461a5.json b/tests/integration/agents/recordings/868820c8d798c0d16063d1750a65ae2632ecf543ee440e7d87ea16f8e83461a5.json index c82ea6394..fa03baf5e 100644 --- a/tests/integration/agents/recordings/868820c8d798c0d16063d1750a65ae2632ecf543ee440e7d87ea16f8e83461a5.json +++ b/tests/integration/agents/recordings/868820c8d798c0d16063d1750a65ae2632ecf543ee440e7d87ea16f8e83461a5.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/86e2b939aabb9dfe7ec712a6b20a5809d6fb56f8c9f92d93030f57cba51a1fe2.json b/tests/integration/agents/recordings/86e2b939aabb9dfe7ec712a6b20a5809d6fb56f8c9f92d93030f57cba51a1fe2.json index c33ecca7e..c702a53aa 100644 --- a/tests/integration/agents/recordings/86e2b939aabb9dfe7ec712a6b20a5809d6fb56f8c9f92d93030f57cba51a1fe2.json +++ b/tests/integration/agents/recordings/86e2b939aabb9dfe7ec712a6b20a5809d6fb56f8c9f92d93030f57cba51a1fe2.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/8c4ec47152697a5b34e44d75af581efbada34e06f59ddf536149871c64c9a247.json b/tests/integration/agents/recordings/8c4ec47152697a5b34e44d75af581efbada34e06f59ddf536149871c64c9a247.json new file mode 100644 index 000000000..9d391c7c8 --- /dev/null +++ b/tests/integration/agents/recordings/8c4ec47152697a5b34e44d75af581efbada34e06f59ddf536149871c64c9a247.json @@ -0,0 +1,442 @@ +{ + "test_id": "tests/integration/agents/test_agents.py::test_create_turn_response[ollama/llama3.2:3b-instruct-fp16-client_tools0]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama3.2:3b-instruct-fp16", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant" + }, + { + "role": "user", + "content": "Call get_boiling_point tool and answer What is the boiling point of polyjuice?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "id": "call_zqu5i0ti", + "type": "function", + "function": { + "name": "get_boiling_point", + "arguments": "{\"celcius\":null,\"liquid_name\":\"polyjuice\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_zqu5i0ti", + "content": "-212" + } + ], + "max_tokens": 512, + "stream": true, + "temperature": 0.0001, + "tool_choice": "auto", + "tools": [ + { + "type": "function", + "function": { + "name": "get_boiling_point", + "description": "Returns the boiling point of a liquid in Celcius or Fahrenheit.", + "parameters": { + "type": "object", + "properties": { + "liquid_name": { + "type": "string", + "description": "The name of the liquid" + }, + "celcius": { + "type": "boolean", + "description": "Whether to return the boiling point in Celcius" + } + }, + "required": [ + "liquid_name" + ] + } + } + } + ], + "top_p": 0.9 + }, + "endpoint": "/v1/chat/completions", + "model": "llama3.2:3b-instruct-fp16" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": " boiling", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": " point", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": " poly", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": "ju", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": "ice", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": " -", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": "212", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": " degrees", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": " Celsius", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8c4ec4715269", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/8ed0947593196c2b2f68035e248c137813e8db50d0d46395ef9ba98636fa5819.json b/tests/integration/agents/recordings/8ed0947593196c2b2f68035e248c137813e8db50d0d46395ef9ba98636fa5819.json index b209de507..15f9b0f96 100644 --- a/tests/integration/agents/recordings/8ed0947593196c2b2f68035e248c137813e8db50d0d46395ef9ba98636fa5819.json +++ b/tests/integration/agents/recordings/8ed0947593196c2b2f68035e248c137813e8db50d0d46395ef9ba98636fa5819.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/8fc418c02b8b6fe09238e36fb72c5e7fc9d41fdaa3eb357f518e0fcaec5ea1e2.json b/tests/integration/agents/recordings/8fc418c02b8b6fe09238e36fb72c5e7fc9d41fdaa3eb357f518e0fcaec5ea1e2.json new file mode 100644 index 000000000..70d92b2bf --- /dev/null +++ b/tests/integration/agents/recordings/8fc418c02b8b6fe09238e36fb72c5e7fc9d41fdaa3eb357f518e0fcaec5ea1e2.json @@ -0,0 +1,59 @@ +{ + "test_id": "tests/integration/agents/test_agents.py::test_tool_choice_get_boiling_point[ollama/llama3.2:3b-instruct-fp16]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama-guard3:1b", + "messages": [ + { + "role": "user", + "content": "Task: Check if there is unsafe content in 'Assistant' messages in conversations according our safety policy with the below categories.\n\n\nS1: Violent Crimes.\nS2: Non-Violent Crimes.\nS3: Sex Crimes.\nS4: Child Exploitation.\nS5: Defamation.\nS6: Specialized Advice.\nS7: Privacy.\nS8: Intellectual Property.\nS9: Indiscriminate Weapons.\nS10: Hate.\nS11: Self-Harm.\nS12: Sexual Content.\nS13: Elections.\nS14: Code Interpreter Abuse.\n\n\n\n\nUser: What is the boiling point of the liquid polyjuice in celsius?\n\nAssistant: \n\nTool: -100\n\nAssistant: The boiling point of liquid polyjuice is -100\u00b0C.\n\n\n\nProvide your safety assessment for ONLY THE LAST Assistant message in the above conversation:\n - First line must read 'safe' or 'unsafe'.\n - If unsafe, a second line must include a comma-separated list of violated categories." + } + ], + "stream": false, + "temperature": 0.0 + }, + "endpoint": "/v1/chat/completions", + "model": "llama-guard3:1b" + }, + "response": { + "body": { + "__type__": "openai.types.chat.chat_completion.ChatCompletion", + "__data__": { + "id": "rec-8fc418c02b8b", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "logprobs": null, + "message": { + "content": "safe", + "refusal": null, + "role": "assistant", + "annotations": null, + "audio": null, + "function_call": null, + "tool_calls": null + } + } + ], + "created": 0, + "model": "llama-guard3:1b", + "object": "chat.completion", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 421, + "total_tokens": 423, + "completion_tokens_details": null, + "prompt_tokens_details": null + } + } + }, + "is_streaming": false + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/901956b3a51b792f2506d603489af51636b480db9cc520614ee4886418776237.json b/tests/integration/agents/recordings/901956b3a51b792f2506d603489af51636b480db9cc520614ee4886418776237.json index 07b7f8331..16078a8c2 100644 --- a/tests/integration/agents/recordings/901956b3a51b792f2506d603489af51636b480db9cc520614ee4886418776237.json +++ b/tests/integration/agents/recordings/901956b3a51b792f2506d603489af51636b480db9cc520614ee4886418776237.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/958f9b74e98bcf41e4988db8ad15494b8fe0ff707261108305353e4ad980195f.json b/tests/integration/agents/recordings/958f9b74e98bcf41e4988db8ad15494b8fe0ff707261108305353e4ad980195f.json index aeb1fe320..ec3117ee3 100644 --- a/tests/integration/agents/recordings/958f9b74e98bcf41e4988db8ad15494b8fe0ff707261108305353e4ad980195f.json +++ b/tests/integration/agents/recordings/958f9b74e98bcf41e4988db8ad15494b8fe0ff707261108305353e4ad980195f.json @@ -1510,5 +1510,6 @@ } ], "is_streaming": true - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/96623a251d6e51ee6ba21c53ca111d4aa54882a124d783a8096fd88adf481065.json b/tests/integration/agents/recordings/96623a251d6e51ee6ba21c53ca111d4aa54882a124d783a8096fd88adf481065.json index 93155e18c..4d8a2a9ce 100644 --- a/tests/integration/agents/recordings/96623a251d6e51ee6ba21c53ca111d4aa54882a124d783a8096fd88adf481065.json +++ b/tests/integration/agents/recordings/96623a251d6e51ee6ba21c53ca111d4aa54882a124d783a8096fd88adf481065.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/a702e4bf918e94acd0d76ed753c120a4704dde82acf5ae198982fd62bd103279.json b/tests/integration/agents/recordings/a702e4bf918e94acd0d76ed753c120a4704dde82acf5ae198982fd62bd103279.json index 1903e3d19..5200b2e65 100644 --- a/tests/integration/agents/recordings/a702e4bf918e94acd0d76ed753c120a4704dde82acf5ae198982fd62bd103279.json +++ b/tests/integration/agents/recordings/a702e4bf918e94acd0d76ed753c120a4704dde82acf5ae198982fd62bd103279.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/ad3f6a2b4031bcd38026c3c50617851f102c12946164a563584e6316bd1b6228.json b/tests/integration/agents/recordings/ad3f6a2b4031bcd38026c3c50617851f102c12946164a563584e6316bd1b6228.json index d6ec4ea4b..52d599fe0 100644 --- a/tests/integration/agents/recordings/ad3f6a2b4031bcd38026c3c50617851f102c12946164a563584e6316bd1b6228.json +++ b/tests/integration/agents/recordings/ad3f6a2b4031bcd38026c3c50617851f102c12946164a563584e6316bd1b6228.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/b3c24a0ab429fb3d7e3680a2a689a8eddb2c2aaf826b513fec55dcd70cdf35ea.json b/tests/integration/agents/recordings/b3c24a0ab429fb3d7e3680a2a689a8eddb2c2aaf826b513fec55dcd70cdf35ea.json new file mode 100644 index 000000000..15a721ef9 --- /dev/null +++ b/tests/integration/agents/recordings/b3c24a0ab429fb3d7e3680a2a689a8eddb2c2aaf826b513fec55dcd70cdf35ea.json @@ -0,0 +1,260 @@ +{ + "test_id": "tests/integration/agents/test_openai_responses.py::test_response_with_instructions[txt=ollama/llama3.2:3b-instruct-fp16]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama3.2:3b-instruct-fp16", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant." + }, + { + "role": "user", + "content": "What is the capital of France?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + } + }, + "endpoint": "/v1/chat/completions", + "model": "llama3.2:3b-instruct-fp16" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3c24a0ab429", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3c24a0ab429", + "choices": [ + { + "delta": { + "content": " capital", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3c24a0ab429", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3c24a0ab429", + "choices": [ + { + "delta": { + "content": " France", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3c24a0ab429", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3c24a0ab429", + "choices": [ + { + "delta": { + "content": " Paris", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3c24a0ab429", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3c24a0ab429", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3c24a0ab429", + "choices": [], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": { + "completion_tokens": 8, + "prompt_tokens": 38, + "total_tokens": 46, + "completion_tokens_details": null, + "prompt_tokens_details": null + } + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/b4a47451a2af579b9dfb4a60bacaee0f274fc53b263c25fe5e9e4bc23739f3db.json b/tests/integration/agents/recordings/b4a47451a2af579b9dfb4a60bacaee0f274fc53b263c25fe5e9e4bc23739f3db.json new file mode 100644 index 000000000..50e14c9fc --- /dev/null +++ b/tests/integration/agents/recordings/b4a47451a2af579b9dfb4a60bacaee0f274fc53b263c25fe5e9e4bc23739f3db.json @@ -0,0 +1,442 @@ +{ + "test_id": "tests/integration/agents/test_agents.py::test_tool_choice_required[ollama/llama3.2:3b-instruct-fp16]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama3.2:3b-instruct-fp16", + "messages": [ + { + "role": "system", + "content": "You are a helpful assistant" + }, + { + "role": "user", + "content": "What is the boiling point of the liquid polyjuice in celsius?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "id": "call_z1rt0qb1", + "type": "function", + "function": { + "name": "get_boiling_point", + "arguments": "{\"celcius\":true,\"liquid_name\":\"polyjuice\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_z1rt0qb1", + "content": "-100" + } + ], + "max_tokens": 512, + "stream": true, + "temperature": 0.0001, + "tool_choice": "required", + "tools": [ + { + "type": "function", + "function": { + "name": "get_boiling_point", + "description": "Returns the boiling point of a liquid in Celcius or Fahrenheit.", + "parameters": { + "type": "object", + "properties": { + "liquid_name": { + "type": "string", + "description": "The name of the liquid" + }, + "celcius": { + "type": "boolean", + "description": "Whether to return the boiling point in Celcius" + } + }, + "required": [ + "liquid_name" + ] + } + } + } + ], + "top_p": 0.9 + }, + "endpoint": "/v1/chat/completions", + "model": "llama3.2:3b-instruct-fp16" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": " boiling", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": " point", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": " liquid", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": " poly", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": "ju", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": "ice", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": " -", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": "100", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": "\u00b0C", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b4a47451a2af", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "llama3.2:3b-instruct-fp16", + "object": "chat.completion.chunk", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": null + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/bcb50763cac6527944653e77df1f2cc9e9481ffae9cff5693b2f669270c9c0a7.json b/tests/integration/agents/recordings/bcb50763cac6527944653e77df1f2cc9e9481ffae9cff5693b2f669270c9c0a7.json index c7ecef75f..4527ab5cd 100644 --- a/tests/integration/agents/recordings/bcb50763cac6527944653e77df1f2cc9e9481ffae9cff5693b2f669270c9c0a7.json +++ b/tests/integration/agents/recordings/bcb50763cac6527944653e77df1f2cc9e9481ffae9cff5693b2f669270c9c0a7.json @@ -66,7 +66,7 @@ "tool_calls": [ { "index": 0, - "id": "call_qryqpevz", + "id": "call_9x4z21g1", "function": { "arguments": "{\"celcius\":\"true\",\"liquid_name\":\"polyjuice\"}", "name": "get_boiling_point" @@ -116,5 +116,6 @@ } ], "is_streaming": true - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/c97c102959ea8c64a43e4c752bf5e979c7a298fdbeedec153954ce817da7e3e7.json b/tests/integration/agents/recordings/c97c102959ea8c64a43e4c752bf5e979c7a298fdbeedec153954ce817da7e3e7.json index e3f54171f..a1332fddb 100644 --- a/tests/integration/agents/recordings/c97c102959ea8c64a43e4c752bf5e979c7a298fdbeedec153954ce817da7e3e7.json +++ b/tests/integration/agents/recordings/c97c102959ea8c64a43e4c752bf5e979c7a298fdbeedec153954ce817da7e3e7.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/ca95f47c2896a7ce1536a3cf1a78170e073e49e478658a4b098b3581a703e843.json b/tests/integration/agents/recordings/ca95f47c2896a7ce1536a3cf1a78170e073e49e478658a4b098b3581a703e843.json index 145596d38..64b28de5c 100644 --- a/tests/integration/agents/recordings/ca95f47c2896a7ce1536a3cf1a78170e073e49e478658a4b098b3581a703e843.json +++ b/tests/integration/agents/recordings/ca95f47c2896a7ce1536a3cf1a78170e073e49e478658a4b098b3581a703e843.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/d35fc2ef48595f5d0afe8fb617c8df864a155017e8d4c5d2e2b2c51e9cfaed5e.json b/tests/integration/agents/recordings/d35fc2ef48595f5d0afe8fb617c8df864a155017e8d4c5d2e2b2c51e9cfaed5e.json index a333490a4..ae1be7520 100644 --- a/tests/integration/agents/recordings/d35fc2ef48595f5d0afe8fb617c8df864a155017e8d4c5d2e2b2c51e9cfaed5e.json +++ b/tests/integration/agents/recordings/d35fc2ef48595f5d0afe8fb617c8df864a155017e8d4c5d2e2b2c51e9cfaed5e.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/da6fc54bb65dd1f83e577109b8228b644e76999ebb2fe8f09bead3dee56a6046.json b/tests/integration/agents/recordings/da6fc54bb65dd1f83e577109b8228b644e76999ebb2fe8f09bead3dee56a6046.json new file mode 100644 index 000000000..f17ae2ae3 --- /dev/null +++ b/tests/integration/agents/recordings/da6fc54bb65dd1f83e577109b8228b644e76999ebb2fe8f09bead3dee56a6046.json @@ -0,0 +1,59 @@ +{ + "test_id": "tests/integration/agents/test_agents.py::test_custom_tool[ollama/llama3.2:3b-instruct-fp16]", + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "llama-guard3:1b", + "messages": [ + { + "role": "user", + "content": "Task: Check if there is unsafe content in 'Assistant' messages in conversations according our safety policy with the below categories.\n\n\nS1: Violent Crimes.\nS2: Non-Violent Crimes.\nS3: Sex Crimes.\nS4: Child Exploitation.\nS5: Defamation.\nS6: Specialized Advice.\nS7: Privacy.\nS8: Intellectual Property.\nS9: Indiscriminate Weapons.\nS10: Hate.\nS11: Self-Harm.\nS12: Sexual Content.\nS13: Elections.\nS14: Code Interpreter Abuse.\n\n\n\n\nUser: What is the boiling point of the liquid polyjuice in celsius?\n\nAssistant: \n\nTool: -100\n\nAssistant: The boiling point of liquid polyjuice is -100\u00b0C.\n\n\n\nProvide your safety assessment for ONLY THE LAST Assistant message in the above conversation:\n - First line must read 'safe' or 'unsafe'.\n - If unsafe, a second line must include a comma-separated list of violated categories." + } + ], + "stream": false, + "temperature": 0.0 + }, + "endpoint": "/v1/chat/completions", + "model": "llama-guard3:1b" + }, + "response": { + "body": { + "__type__": "openai.types.chat.chat_completion.ChatCompletion", + "__data__": { + "id": "rec-da6fc54bb65d", + "choices": [ + { + "finish_reason": "stop", + "index": 0, + "logprobs": null, + "message": { + "content": "safe", + "refusal": null, + "role": "assistant", + "annotations": null, + "audio": null, + "function_call": null, + "tool_calls": null + } + } + ], + "created": 0, + "model": "llama-guard3:1b", + "object": "chat.completion", + "service_tier": null, + "system_fingerprint": "fp_ollama", + "usage": { + "completion_tokens": 2, + "prompt_tokens": 421, + "total_tokens": 423, + "completion_tokens_details": null, + "prompt_tokens_details": null + } + } + }, + "is_streaming": false + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/agents/recordings/db5c89b87eba0d129ad9ed17306d4016aeeaf2bbeeaa5643d9620f5ea484430e.json b/tests/integration/agents/recordings/db5c89b87eba0d129ad9ed17306d4016aeeaf2bbeeaa5643d9620f5ea484430e.json index da06f3968..55e71cf27 100644 --- a/tests/integration/agents/recordings/db5c89b87eba0d129ad9ed17306d4016aeeaf2bbeeaa5643d9620f5ea484430e.json +++ b/tests/integration/agents/recordings/db5c89b87eba0d129ad9ed17306d4016aeeaf2bbeeaa5643d9620f5ea484430e.json @@ -71,7 +71,7 @@ "tool_calls": [ { "index": 0, - "id": "call_ur5tbdbt", + "id": "call_5qverjg6", "function": { "arguments": "{\"celcius\":true,\"liquid_name\":\"polyjuice\"}", "name": "get_boiling_point" @@ -121,5 +121,6 @@ } ], "is_streaming": true - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/ed76dd5fdf892c9cc959b2d301a256f81c43a906a0a56684ca97e848f8d6a94c.json b/tests/integration/agents/recordings/ed76dd5fdf892c9cc959b2d301a256f81c43a906a0a56684ca97e848f8d6a94c.json index cb2afc5ed..06d8a4305 100644 --- a/tests/integration/agents/recordings/ed76dd5fdf892c9cc959b2d301a256f81c43a906a0a56684ca97e848f8d6a94c.json +++ b/tests/integration/agents/recordings/ed76dd5fdf892c9cc959b2d301a256f81c43a906a0a56684ca97e848f8d6a94c.json @@ -54,5 +54,6 @@ } }, "is_streaming": false - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/recordings/f85c3c14185386eecd4939eeb6b3a3cee734d69beb7cd6d13a3d3c2c64eca734.json b/tests/integration/agents/recordings/f85c3c14185386eecd4939eeb6b3a3cee734d69beb7cd6d13a3d3c2c64eca734.json index 2e1e9f4e5..dbb70df6c 100644 --- a/tests/integration/agents/recordings/f85c3c14185386eecd4939eeb6b3a3cee734d69beb7cd6d13a3d3c2c64eca734.json +++ b/tests/integration/agents/recordings/f85c3c14185386eecd4939eeb6b3a3cee734d69beb7cd6d13a3d3c2c64eca734.json @@ -66,7 +66,7 @@ "tool_calls": [ { "index": 0, - "id": "call_rq1pcgq7", + "id": "call_z1rt0qb1", "function": { "arguments": "{\"celcius\":true,\"liquid_name\":\"polyjuice\"}", "name": "get_boiling_point" @@ -116,5 +116,6 @@ } ], "is_streaming": true - } + }, + "id_normalization_mapping": {} } diff --git a/tests/integration/agents/test_openai_responses.py b/tests/integration/agents/test_openai_responses.py index 675e2b904..d413d5201 100644 --- a/tests/integration/agents/test_openai_responses.py +++ b/tests/integration/agents/test_openai_responses.py @@ -466,3 +466,53 @@ def test_guardrails_with_tools(compat_client, text_model_id): # Response should be either a function call or a message output_type = response.output[0].type assert output_type in ["function_call", "message"] + + +def test_response_with_instructions(openai_client, client_with_models, text_model_id): + """Test instructions parameter in the responses object.""" + if isinstance(client_with_models, LlamaStackAsLibraryClient): + pytest.skip("OpenAI responses are not supported when testing with library client yet.") + + client = openai_client + + messages = [ + { + "role": "user", + "content": "What is the capital of France?", + } + ] + + # First create a response without instructions parameter + response_w_o_instructions = client.responses.create( + model=text_model_id, + input=messages, + stream=False, + ) + + # Verify we have None in the instructions field + assert response_w_o_instructions.instructions is None + + # Next create a response and pass instructions parameter + instructions = "You are a helpful assistant." + response_with_instructions = client.responses.create( + model=text_model_id, + instructions=instructions, + input=messages, + stream=False, + ) + + # Verify we have a valid instructions field + assert response_with_instructions.instructions == instructions + + # Finally test instructions parameter with a previous response id + instructions2 = "You are a helpful assistant and speak in pirate language." + response_with_instructions2 = client.responses.create( + model=text_model_id, + instructions=instructions2, + input=messages, + previous_response_id=response_with_instructions.id, + stream=False, + ) + + # Verify instructions from previous response was not carried over to the next response + assert response_with_instructions2.instructions == instructions2 diff --git a/tests/integration/common/recordings/models-64a2277c90f0f42576f60c1030e3a020403d34a95f56931b792d5939f4cebc57-abd54ea0.json b/tests/integration/common/recordings/models-64a2277c90f0f42576f60c1030e3a020403d34a95f56931b792d5939f4cebc57-abd54ea0.json new file mode 100644 index 000000000..77e244a01 --- /dev/null +++ b/tests/integration/common/recordings/models-64a2277c90f0f42576f60c1030e3a020403d34a95f56931b792d5939f4cebc57-abd54ea0.json @@ -0,0 +1,44 @@ +{ + "test_id": null, + "request": { + "method": "POST", + "url": "http://0.0.0.0:11434/v1/v1/models", + "headers": {}, + "body": {}, + "endpoint": "/v1/models", + "model": "" + }, + "response": { + "body": [ + { + "__type__": "openai.types.model.Model", + "__data__": { + "id": "llama-guard3:1b", + "created": 1753937098, + "object": "model", + "owned_by": "library" + } + }, + { + "__type__": "openai.types.model.Model", + "__data__": { + "id": "all-minilm:l6-v2", + "created": 1753936935, + "object": "model", + "owned_by": "library" + } + }, + { + "__type__": "openai.types.model.Model", + "__data__": { + "id": "llama3.2:3b-instruct-fp16", + "created": 1753936925, + "object": "model", + "owned_by": "library" + } + } + ], + "is_streaming": false + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py index 3137de0de..18878c5f4 100644 --- a/tests/integration/conftest.py +++ b/tests/integration/conftest.py @@ -5,6 +5,7 @@ # the root directory of this source tree. import inspect import itertools +import logging # allow-direct-logging import os import tempfile import textwrap @@ -37,6 +38,9 @@ def pytest_sessionstart(session): if "LLAMA_STACK_TEST_INFERENCE_MODE" not in os.environ: os.environ["LLAMA_STACK_TEST_INFERENCE_MODE"] = "replay" + if "LLAMA_STACK_LOGGING" not in os.environ: + os.environ["LLAMA_STACK_LOGGING"] = "all=warning" + if "SQLITE_STORE_DIR" not in os.environ: os.environ["SQLITE_STORE_DIR"] = tempfile.mkdtemp() @@ -54,6 +58,12 @@ def pytest_sessionstart(session): patch_httpx_for_test_id() +@pytest.fixture(autouse=True) +def suppress_httpx_logs(caplog): + """Suppress httpx INFO logs for all integration tests""" + caplog.set_level(logging.WARNING, logger="httpx") + + @pytest.fixture(autouse=True) def _track_test_context(request): """Automatically track current test context for isolated recordings. @@ -317,3 +327,72 @@ def pytest_ignore_collect(path: str, config: pytest.Config) -> bool: if p.is_relative_to(rp): return False return True + + +def get_vector_io_provider_ids(client): + """Get all available vector_io provider IDs.""" + providers = [p for p in client.providers.list() if p.api == "vector_io"] + return [p.provider_id for p in providers] + + +def vector_provider_wrapper(func): + """Decorator to run a test against all available vector_io providers.""" + import functools + import os + + @functools.wraps(func) + def wrapper(*args, **kwargs): + # Get the vector_io_provider_id from the test arguments + import inspect + + sig = inspect.signature(func) + bound_args = sig.bind(*args, **kwargs) + bound_args.apply_defaults() + + vector_io_provider_id = bound_args.arguments.get("vector_io_provider_id") + if not vector_io_provider_id: + pytest.skip("No vector_io_provider_id provided") + + # Get client_with_models to check available providers + client_with_models = bound_args.arguments.get("client_with_models") + if client_with_models: + available_providers = get_vector_io_provider_ids(client_with_models) + if vector_io_provider_id not in available_providers: + pytest.skip(f"Provider '{vector_io_provider_id}' not available. Available: {available_providers}") + + return func(*args, **kwargs) + + # For replay tests, only use providers that are available in ci-tests environment + if os.environ.get("LLAMA_STACK_TEST_INFERENCE_MODE") == "replay": + all_providers = ["faiss", "sqlite-vec"] + else: + # For live tests, try all providers (they'll skip if not available) + all_providers = [ + "faiss", + "sqlite-vec", + "milvus", + "chromadb", + "pgvector", + "weaviate", + "qdrant", + ] + + return pytest.mark.parametrize("vector_io_provider_id", all_providers)(wrapper) + + +@pytest.fixture +def vector_io_provider_id(request, client_with_models): + """Fixture that provides a specific vector_io provider ID, skipping if not available.""" + if hasattr(request, "param"): + requested_provider = request.param + available_providers = get_vector_io_provider_ids(client_with_models) + + if requested_provider not in available_providers: + pytest.skip(f"Provider '{requested_provider}' not available. Available: {available_providers}") + + return requested_provider + else: + provider_ids = get_vector_io_provider_ids(client_with_models) + if not provider_ids: + pytest.skip("No vector_io providers available") + return provider_ids[0] diff --git a/tests/integration/fixtures/common.py b/tests/integration/fixtures/common.py index 68a30fc69..6a9e1f3b2 100644 --- a/tests/integration/fixtures/common.py +++ b/tests/integration/fixtures/common.py @@ -21,6 +21,7 @@ from llama_stack_client import LlamaStackClient from openai import OpenAI from llama_stack import LlamaStackAsLibraryClient +from llama_stack.core.datatypes import VectorStoresConfig from llama_stack.core.stack import run_config_from_adhoc_config_spec from llama_stack.env import get_env_or_fail @@ -39,7 +40,7 @@ def is_port_available(port: int, host: str = "localhost") -> bool: def start_llama_stack_server(config_name: str) -> subprocess.Popen: """Start a llama stack server with the given config.""" - cmd = f"uv run --with llama-stack llama stack build --distro {config_name} --image-type venv --run" + cmd = f"uv run llama stack run {config_name}" devnull = open(os.devnull, "w") process = subprocess.Popen( shlex.split(cmd), @@ -236,9 +237,16 @@ def instantiate_llama_stack_client(session): if "=" in config: run_config = run_config_from_adhoc_config_spec(config) + + # --stack-config bypasses template so need this to set default embedding model + if "vector_io" in config and "inference" in config: + run_config.vector_stores = VectorStoresConfig( + embedding_model_id="inline::sentence-transformers/nomic-ai/nomic-embed-text-v1.5" + ) + run_config_file = tempfile.NamedTemporaryFile(delete=False, suffix=".yaml") with open(run_config_file.name, "w") as f: - yaml.dump(run_config.model_dump(), f) + yaml.dump(run_config.model_dump(mode="json"), f) config = run_config_file.name client = LlamaStackAsLibraryClient( diff --git a/tests/integration/providers/utils/sqlstore/test_authorized_sqlstore.py b/tests/integration/providers/utils/sqlstore/test_authorized_sqlstore.py index 98bef0f2c..ad9115756 100644 --- a/tests/integration/providers/utils/sqlstore/test_authorized_sqlstore.py +++ b/tests/integration/providers/utils/sqlstore/test_authorized_sqlstore.py @@ -12,9 +12,15 @@ import pytest from llama_stack.core.access_control.access_control import default_policy from llama_stack.core.datatypes import User +from llama_stack.core.storage.datatypes import SqlStoreReference from llama_stack.providers.utils.sqlstore.api import ColumnType from llama_stack.providers.utils.sqlstore.authorized_sqlstore import AuthorizedSqlStore -from llama_stack.providers.utils.sqlstore.sqlstore import PostgresSqlStoreConfig, SqliteSqlStoreConfig, sqlstore_impl +from llama_stack.providers.utils.sqlstore.sqlstore import ( + PostgresSqlStoreConfig, + SqliteSqlStoreConfig, + register_sqlstore_backends, + sqlstore_impl, +) def get_postgres_config(): @@ -55,8 +61,9 @@ def authorized_store(backend_config): config_func = backend_config config = config_func() - - base_sqlstore = sqlstore_impl(config) + backend_name = f"sql_{type(config).__name__.lower()}" + register_sqlstore_backends({backend_name: config}) + base_sqlstore = sqlstore_impl(SqlStoreReference(backend=backend_name, table_name="authorized_store")) authorized_store = AuthorizedSqlStore(base_sqlstore, default_policy()) yield authorized_store diff --git a/tests/integration/responses/recordings/00913934356fb4f196f8c21081154c67a7197dcc26e0326cf72448334c21424d.json b/tests/integration/responses/recordings/00913934356fb4f196f8c21081154c67a7197dcc26e0326cf72448334c21424d.json new file mode 100644 index 000000000..c6ffb34ae --- /dev/null +++ b/tests/integration/responses/recordings/00913934356fb4f196f8c21081154c67a7197dcc26e0326cf72448334c21424d.json @@ -0,0 +1,660 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search[openai_client-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768-llama_experts_pdf]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "id": "call_M8gyYiB39MwYdJKc4aHIGbfA", + "function": { + "arguments": "", + "name": "knowledge_search" + }, + "type": "function" + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8anw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "{\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "99M" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "query", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "I" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\":\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "L", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ptMnH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "lama", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ue" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " ", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Euqoc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "4", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zdLoy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " Maver", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "ick", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Dq4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " model", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " number", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nAZItljCEdlp1VF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " of", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9VZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " experts", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JqBWo7hfEH8khh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\"}", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hls" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "tool_calls", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KHtw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-00913934356f", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 24, + "prompt_tokens": 74, + "total_tokens": 98, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "94SeGMt8IytX52R" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/0c81f5d5c9e09daecd5eceaeae22bf228addd43f95f4a9ede8bd5a3cfbd091af.json b/tests/integration/responses/recordings/0c81f5d5c9e09daecd5eceaeae22bf228addd43f95f4a9ede8bd5a3cfbd091af.json new file mode 100644 index 000000000..124ac58f8 --- /dev/null +++ b/tests/integration/responses/recordings/0c81f5d5c9e09daecd5eceaeae22bf228addd43f95f4a9ede8bd5a3cfbd091af.json @@ -0,0 +1,1060 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_filter_compound_and[client_with_models-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "What are the engineering updates from the US?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_rST37XuKuJQcEBfmoTnNQzNe", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"engineering updates from the US\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_rST37XuKuJQcEBfmoTnNQzNe", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-710505118847, score: 0.0053456084826297495, attributes: {'region': 'us', 'category': 'engineering', 'date': 1680307200.0, 'filename': 'us_engineering_q2.txt', 'document_id': 'file-710505118847', 'token_count': 18.0, 'metadata_token_count': 32.0} (cite as <|file-710505118847|>)\nUS technical updates for Q2 2023. New features deployed in the US region.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"engineering updates from the US\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "z02myeBc6IWePG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kUl1Dgvb1xGk0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " latest", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mFba9527A" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " engineering", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CuR9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " updates", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "b33WbQ32" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " from", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ybBU6K61695" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CS7fwXovMF3s" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9SyeqBDvQ2F3A" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " include", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "w3TeXaqI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " new", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Fz7AHFsFIYoJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " features", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "In5n8Bd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " that", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "n1o5yYMnIMN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " were", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bg19HslIylq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " deployed", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JmwcZYf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "b2vPax6xpus1H" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "atkHzevglgp8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "i7GGwqsH3vDMq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HCEDdIsLl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XGsBo410Yxpw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qGOs1cXLinho8b" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "2", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Fi1yFeDxgl9HIpw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HHz8qM9mtMGqDCp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aqfdHJ5pgR6zr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rpqQ271sC7BNlof" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5SaeSMndmAH3Rk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FRggMDh3RIYByfw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VO19FFBENZdX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ff4aGYwzBDQQl6V" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "710", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1JmjekVJz175r" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "505", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "uXUPxMmKofAwR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "118", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "b9FFeyPKWaapF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "847", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "48t9A4JN46znF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "60SAkGxGOFZsqKW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1OYEmPtXR2Q2n8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "37pmsVabd3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-0c81f5d5c9e0", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 34, + "prompt_tokens": 340, + "total_tokens": 374, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "9uLZBXCb5sbUa" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/1489591da67e505cdd2c1fddb0c3fb8372e880782d7783dd24b13689686a54e1.json b/tests/integration/responses/recordings/1489591da67e505cdd2c1fddb0c3fb8372e880782d7783dd24b13689686a54e1.json new file mode 100644 index 000000000..749f9a995 --- /dev/null +++ b/tests/integration/responses/recordings/1489591da67e505cdd2c1fddb0c3fb8372e880782d7783dd24b13689686a54e1.json @@ -0,0 +1,668 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_sequential_file_search[openai_client-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_4ac6gxccWFxDvEl8BizY3BJw", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model number of experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_4ac6gxccWFxDvEl8BizY3BJw", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-528246887823, score: 0.01927231682811354, attributes: {'filename': 'test_sequential_file_search.txt', 'document_id': 'file-528246887823', 'token_count': 19.0, 'metadata_token_count': 11.0} (cite as <|file-528246887823|>)\nThe Llama 4 Maverick model has 128 experts in its mixture of experts architecture.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model number of experts\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + }, + { + "role": "assistant", + "content": "The Llama 4 Maverick model has 128 experts in its mixture of experts architecture <|file-528246887823|>." + }, + { + "role": "user", + "content": "Can you tell me more about the architecture?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "id": "call_rmMfpryevUEhVly9yXhlsVG0", + "function": { + "arguments": "", + "name": "knowledge_search" + }, + "type": "function" + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "34Bp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "{\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZFY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "query", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "w" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\":\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "B" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "L", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tJ1px" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "lama", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " ", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "E6ImC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "4", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "h3NL0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " Maver", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "ick", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "18C" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " model", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " architecture", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "l4ejZ7nxo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " details", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1i292QtpWi65ci" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\"}", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EWU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "tool_calls", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hNDG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1489591da67e", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 23, + "prompt_tokens": 377, + "total_tokens": 400, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "TajyNPPmLXMy1" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/15f4d677d61a2eecaedd1aafaa3925d76f5e98199f0c6baf6736bb140e008cff.json b/tests/integration/responses/recordings/15f4d677d61a2eecaedd1aafaa3925d76f5e98199f0c6baf6736bb140e008cff.json new file mode 100644 index 000000000..54aac096c --- /dev/null +++ b/tests/integration/responses/recordings/15f4d677d61a2eecaedd1aafaa3925d76f5e98199f0c6baf6736bb140e008cff.json @@ -0,0 +1,763 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search[openai_client-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768-llama_experts]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_UKFNZA0eSkL6fZHbs8ygBd5W", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model number of experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_UKFNZA0eSkL6fZHbs8ygBd5W", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-861837565219, score: 0.015252756439527764, attributes: {'filename': 'test_response_non_streaming_file_search.txt', 'document_id': 'file-861837565219', 'token_count': 10.0, 'metadata_token_count': 13.0} (cite as <|file-861837565219|>)\nLlama 4 Maverick has 128 experts\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model number of experts\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "t286ibBdBtIrgr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "U9mPebT93jaD6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": " L", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JJ5Xp0JfYMykC6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "lama", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oxaRGhfy0xhA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DSR2mw4mJJpT9TQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "4", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QR8qbwLCtyBsNPE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": " Maver", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lb79bMu1aH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "ick", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "siOOzlWO8l75q" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7azbsqKmkb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": " has", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AGmv3xp6PWIL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fZjTPPdOZO2fpsH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "128", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7jbYm9zpbFY8u" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GKSrKriL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "U9Rqtd9YhQ2ARK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2HSPrSu1pk90PIF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OPPb0thERVPI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dLA839tLWqtODM5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "861", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sRR5OHXHSzinH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "837", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "r3aqOeXUsyjjZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "565", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gsi9YE8xBivSU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "219", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zGSdQm7vspYCY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "m8Wm3YWMwlQ8zl5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lCLlH34nfjTsEB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rTGBImqnxH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-15f4d677d61a", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 23, + "prompt_tokens": 326, + "total_tokens": 349, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "HWpBZq9m6jgEu" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/1ce6d4a8ec438d4a6a3618e5e6929b2db20e03a629092274039f33f909bd481d.json b/tests/integration/responses/recordings/1ce6d4a8ec438d4a6a3618e5e6929b2db20e03a629092274039f33f909bd481d.json new file mode 100644 index 000000000..f3ec20028 --- /dev/null +++ b/tests/integration/responses/recordings/1ce6d4a8ec438d4a6a3618e5e6929b2db20e03a629092274039f33f909bd481d.json @@ -0,0 +1,6723 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_filter_compound_or[openai_client-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "Show me marketing and sales documents" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_u8kC9t9arrSV758kavJmcZE7", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\": \"marketing documents\"}" + } + }, + { + "index": 1, + "id": "call_jnsNgiHFvrr6kNsUUFsiCSdh", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\": \"sales documents\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_u8kC9t9arrSV758kavJmcZE7", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 3 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-862946202234, score: 0.002369960119027428, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-862946202234', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-862946202234|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-862946202236, score: 0.002158784645354334, attributes: {'region': 'eu', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'eu_marketing_q1.txt', 'document_id': 'file-862946202236', 'token_count': 17.0, 'metadata_token_count': 32.0} (cite as <|file-862946202236|>)\nEuropean advertising campaign results for Q1 2023. Strong growth in EU markets.\n" + }, + { + "type": "text", + "text": "[3] document_id: file-862946202237, score: 0.0018325740484518083, attributes: {'region': 'asia', 'category': 'sales', 'date': 1688169600.0, 'filename': 'asia_sales_q3.txt', 'document_id': 'file-862946202237', 'token_count': 17.0, 'metadata_token_count': 31.0} (cite as <|file-862946202237|>)\nAsia Pacific revenue figures for Q3 2023. Record breaking quarter in Asia.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"marketing documents\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_jnsNgiHFvrr6kNsUUFsiCSdh", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 3 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-862946202234, score: 0.0020592709044779337, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-862946202234', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-862946202234|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-862946202237, score: 0.0017944759843167356, attributes: {'region': 'asia', 'category': 'sales', 'date': 1688169600.0, 'filename': 'asia_sales_q3.txt', 'document_id': 'file-862946202237', 'token_count': 17.0, 'metadata_token_count': 31.0} (cite as <|file-862946202237|>)\nAsia Pacific revenue figures for Q3 2023. Record breaking quarter in Asia.\n" + }, + { + "type": "text", + "text": "[3] document_id: file-862946202236, score: 0.0017688937698533602, attributes: {'region': 'eu', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'eu_marketing_q1.txt', 'document_id': 'file-862946202236', 'token_count': 17.0, 'metadata_token_count': 32.0} (cite as <|file-862946202236|>)\nEuropean advertising campaign results for Q1 2023. Strong growth in EU markets.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"sales documents\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZSn5MU697qcVQ4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "Here", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "N5rvfm91T309" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " are", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BnE3ln7FQFHR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " some", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ld48GYDc6in" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " documents", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NPDnkz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " related", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UvoOoM6v" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " to", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2IKW0KTWR8zQr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xoBkRY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " and", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "01vXxfssKxLV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " sales", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EmtDdapoDN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ":\n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eSQwScAWiDX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "###", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kuY4neoRsfkxF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GtWbWs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Documents", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sSa6sO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yvIC7j5hxVVfxc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "D56Q6NAhOLJxxJV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "uuxSWHYLaWRoxcZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "W4q7u2IGJ1cqW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UCut703pWstb5C" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nLdC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Campaign", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wj7Ybyv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "s", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BRB0ZPvRFgYBq5J" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "daThBK1Hd73d" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YFtRkxbVcP9eRI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IzQGtpVbMWGJEA5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ub2Sh1354LjHYIM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Wa1FlElzIeKC6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "j4ZkGA52KHr1o5r" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YVZfVuIMH81Fw5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ":", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pJbNyltqBt775dA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " This", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WY6mDwv7AaM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " document", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cC3BxMT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " details", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "z7xvM6yp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WNnqIL0fWlDq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LZrx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " activities", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tQrV6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oLVIPYnHkP5dr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3gISF78q0DRu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ls69lpHG3rRx6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tMvk4e249ILg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8sIH3McPjuym" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " first", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "axSYBsqVbX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " quarter", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HBHla0nN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "k9acPLLCzOmDs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZjCNQxh4RmGiaVP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yAQJW35m3Z0ja" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RdbikHwApG8FoYJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "daA1mimSDXfi5j9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " highlighting", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ohL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FYZpg4zMI5XJUH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FoXIfbNG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " increase", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Rn8Gsba" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " by", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "iRgBjHh7HKzTC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gyVLAZl8FTQYHVO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "15", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Dbdz3ymUwLPDZ4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "%", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Fjn0sTn07sIFE41" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "q3dOBzJqrifsk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " this", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "c82LOs4HUhX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DoWDJqW4B" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EEpzsNyTvIddgo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "69bYP78C7LdVThc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MGUjVE6I56xN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FVA0doOgyhUC9bE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "862", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qyvunLxeXuZAI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "946", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4IBwieJ5z61NJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HqCtGPtnhmBmW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "234", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GgJzwrzKyS473" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Qn9Myp6Naw2xyQC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ">.\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DtgLgc2QDB3h" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " \n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LRxo3rHkDD0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "2", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5ACr0Kg4v5j5vzQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DrIgN8Ww5rVp8RR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dSzOTxzgIrch7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "European", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Cb28jVDi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Advertising", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jUO1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Campaign", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZHIMVAb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Results", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Q3kSrmTN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RD44hoH1DTiM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ztFlaZWQyZELws" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gkUdqOgD489rlgh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8pHGGfwX5bupAiu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "I5RI8t99fTAnT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TPGCVZhdORYyUso" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NKYb4ZofJRoO65" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ":", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "uWHRYYt2AAO80Vp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " It", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VX6xRNnELKJiP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " discusses", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9BtLn8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6G73KnJPioIt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " outcomes", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eVgLMpV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pN6K4uLcdpHFe" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " advertising", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0JRA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SL6QA6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5dD1qSwkbfbeK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Europe", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zvTQh175d" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " during", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "D4NcIH1fg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FjhfLgXetRhw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " first", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xnacPUExMF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " quarter", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CYFtn9cZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Tynjh655EpxTK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "f45nWaexWZUMqtN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bqDO5l1Sp2hTO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LWHGxd0sgAuHzyP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "F4pRJcsW6hfIFFz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " noting", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dcU3WwS9n" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " strong", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4HCofu7jO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " growth", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zF1Rh7iFX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AMCVMvK5fU7xg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "e5nPK6tn3mVc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " EU", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "476R1ts4iH8Gi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " markets", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3uWY64P6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Zf84rhoyo7hcyp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NF5n6ghSkfXuE5A" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ewuNDF8jJ7Uo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Euckmu1Vho0CnUw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "862", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HMTb2RxboE8wx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "946", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QXGbLrEGs3AbQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6ASPJQ2K7l60j" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "236", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4qO1Fx4Rn0WA2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xIlg7gvAj8o6bHF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ">", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "X35mrv2YIZgmszg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ".\n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UPvfKr3wR80" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "###", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nh05VUr5PvpAE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Sales", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YhFb2tctXf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Documents", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "juVXu9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GuBMFMot5Okurj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "iVlWQlpYwHZ0rMF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0uHQl8LisHK3jhv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HYAgTIo5f99uD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "Asia", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XSEJzZ5P0aKf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Pacific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0nxQ1yPS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AC9XfL2Q" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Figures", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YpOIIz7w" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SbN1o0MwMeQr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZRXCR7wXxKdXJ1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yBUQXXuqZ6dBsPd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yGj7EQw6tP3LywU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "srG2DC0vZdB37" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TjPJmmCBd2fuDs0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VIZh5eno1bbsFB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ":", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aKwDKEJADUJORoz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " This", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FretDy4Futo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " document", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vbYCHw9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " covers", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oj8liB3kv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "itK5tlPl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " statistics", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2SL0D" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ktLnqRi127I5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bTyFNrCgfI6N" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Asia", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "y3qyzQmTyH0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Pacific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nlXxtMB0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4pC1KKh0w" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xcBBzIHkT6Fd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kITvhZmoukMA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " third", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qHQcQlCLpv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " quarter", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Q3KgEC7j" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WRR6vlJQwjdTl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JG07QWwlfVeco7x" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4NXAthMUA4Qzl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "td2IvdQUzIOXpqr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pCJBykZRe4wZPJR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " mentioning", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5pXKA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pTOCoRBWAUBOKJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " record", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IChoBPnsP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "-breaking", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Vl5dwhC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " quarter", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dCDYP3a9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Q13RfKMkp4jwG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Asia", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "uOvX3cLc4FX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gLXYXZeBf4uMpD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aI5Qz9VhQXMONoS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EGh7O7FPZO3w" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AQlzDuMDeqViVrI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "862", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "34Zt9YaRkG003" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "946", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "e6OZUZsfDPUAD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gDc70adNF6PJp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "237", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bOoJ3hFFRsvy8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DcdTUsRqijIv1J7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ">.\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gGUrBIod9AgX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " \n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ijXZF1gNJvS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "2", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "n4icsblmJuBmca4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gIDXROijGQcx5ZI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hdOQoT47ezZqP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1eQZ168LK4VOhh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3oZ8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Campaign", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8ZTPtnu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "s", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CEWFDGeUTJkAgGP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gC4ViREbO3ot" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wahQTx95ri1gdS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fVJx0RllRW0Sahq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "89XlLGJA13AAI8D" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RmlGtxMuOpdh4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Le90Cz7Inbx4RMw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ogN5Ew0YI4CAYy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ":", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WDxTolMvtXnpdfX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " Although", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Vxgyj3i" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " primarily", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "O2IYtt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " categorized", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wF46" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " under", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Z3JrsP0GbX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "npJRat" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6ZU02R0AQ2jDTGq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " this", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cyWEzi1CSnQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " document", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mOBT6Ab" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " also", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hMz3iSEsAh2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " has", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "r1BBblrkREmz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " relevance", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ermGzl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " to", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VTVxOmOxgGknP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " sales", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mbkSyaLXkG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " as", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "g13POliiVwayx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " it", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3AwnFnlXUfX4s" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " involves", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VaON0Vx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QhErgFM3vYAF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " analysis", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Uyf3TSV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OqWJXtRf4gcIx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gdnTayeW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " changes", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5iNpMfbY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZuhnRvLuqpzC4w" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kLfrVErEbhir8Do" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9dhpXM9ztANt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EUrwM0uCZILPwbE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "862", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vjDqmKD84fyJ6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "946", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SMipXWMp3pEEX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nyGIshkiDvwCd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "234", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tE16biIaPEMTe" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "j15mOPb6b1unsyF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ozEB87JDmu00NE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " \n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Uj0Vb5VOrcg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": "These", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WYLTY6e2vno" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " documents", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jxjdUT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " provide", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KrQNppag" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " insights", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YLUPb4b" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " into", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7axYpHyeAWe" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "02Agp69cShi6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " regional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JHjQo8g" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PgIzcu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " strategies", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Cd8cL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " and", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Jy9Dy0psteq2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " sales", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "t4hjR7XoVT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " outcomes", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CWvmgkQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " across", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TVj652ly7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " different", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rjGeSA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " quarters", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FPMjFh3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " and", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PHpv4jRUd7bK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": " regions", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mUBTbAYP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EGgMOrYAAh08mtZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hY8fxXrfEG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-1ce6d4a8ec43", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 242, + "prompt_tokens": 1132, + "total_tokens": 1374, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "WBmBP4MZXT" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/302881895eae2384296096186c02053183a19c75d8a55f0d19ae51e36c7aa673.json b/tests/integration/responses/recordings/302881895eae2384296096186c02053183a19c75d8a55f0d19ae51e36c7aa673.json new file mode 100644 index 000000000..c466608fa --- /dev/null +++ b/tests/integration/responses/recordings/302881895eae2384296096186c02053183a19c75d8a55f0d19ae51e36c7aa673.json @@ -0,0 +1,2098 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_streaming_events[client_with_models-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "What are the marketing updates?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_yrecP7RchFwSrzeZd9oqtJEN", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"marketing updates\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_yrecP7RchFwSrzeZd9oqtJEN", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 4 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-450428750203, score: 0.0030630316348127453, attributes: {'region': 'us', 'category': 'engineering', 'date': 1680307200.0, 'filename': 'us_engineering_q2.txt', 'document_id': 'file-450428750203', 'token_count': 18.0, 'metadata_token_count': 32.0} (cite as <|file-450428750203|>)\nUS technical updates for Q2 2023. New features deployed in the US region.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-450428750202, score: 0.00301975206110427, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-450428750202', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-450428750202|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "[3] document_id: file-450428750204, score: 0.002866717244815973, attributes: {'region': 'eu', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'eu_marketing_q1.txt', 'document_id': 'file-450428750204', 'token_count': 17.0, 'metadata_token_count': 32.0} (cite as <|file-450428750204|>)\nEuropean advertising campaign results for Q1 2023. Strong growth in EU markets.\n" + }, + { + "type": "text", + "text": "[4] document_id: file-450428750205, score: 0.0019597433267324765, attributes: {'region': 'asia', 'category': 'sales', 'date': 1688169600.0, 'filename': 'asia_sales_q3.txt', 'document_id': 'file-450428750205', 'token_count': 17.0, 'metadata_token_count': 31.0} (cite as <|file-450428750205|>)\nAsia Pacific revenue figures for Q3 2023. Record breaking quarter in Asia.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"marketing updates\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Xrpaygosn3510z" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "Here", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BDhCBGQGwHks" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " are", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1YOHEXVDsAru" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " some", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zZZZOpKAJrJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " recent", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2MtDOZdjv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "j1d6lW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " updates", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2bQFZIbH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": ":\n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3InKOEf7d3o" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JKvbPCoVtsniccE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qnkkTohRT7WYkBH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " In", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZlSVQRmmCBS66" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2Ztjdp9QczZw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7wAKBKHBJphPI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "T3H80NXNTxv8bbl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " during", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Mxe1tPuKr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OmFjU6i9BJmOrF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "y4v82Z8RabRd65u" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "V2ciLYK8qMR6Rzl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0yv5NxNRvva48" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZdB24d9AeAaxlqZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pc8uBQ8vk4xe99b" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pyop" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mZ619w" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " led", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Flzbq5h5oWUm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " to", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "csLmQWyQS7yE2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4SfMx0zFKjlA07" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "m3fMpBht4RUPbRE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "15", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kpOYKfyP50Jy8h" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "%", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "h30qslU2SXZlEf5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " increase", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Eoygzpq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "f4mMz9JFlwYov" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "22kmNpJ3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MGCBeVQsEwzbj5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1AYK7MCKVvhCfat" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1jCpbAxQCTNM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fwX0vWKzabyT1Ce" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "450", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6eNOFlqExVRbL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "428", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "O4MO1BpdX45AX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "750", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "b36tIskCwCBM7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WVog3EE4vswE6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BmYKOpwDCEJ0bC0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": ">.\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "svmsQJDnvg0v" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "2", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fro1EcEmv8FGmRr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yA7QHUxA9ts6gzl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " In", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GmIpQJVXKWriu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " Europe", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HDunCtP3I" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "M1pwq5Il682ZM5q" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " advertising", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "m855" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Osx0co" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jz0B9Lk3AKaoT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OPPNsXii2uB8z6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ibqCwWa8p3zffbU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DSihoAJ6GjECKbg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cBygMtobAWYY0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YgtcLvYzUDRfAav" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " showed", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DaJComzu6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " strong", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "StVHFW8sz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " growth", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "f6lNyMRm6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5RUEmAr9oCfAW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yQtdd0Gc8IxY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " EU", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HanFX4Mzz2VVD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " markets", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "p1tHf86M" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "k1HdwVaHZao7R8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qSUxyyJxMJEuL7n" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7xVgSj2f2FLU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hyOMOnQHaawCguP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "450", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KnedBZG6e6Y15" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "428", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "n6KeCl7WDRWm4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "750", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "60EAbQzepegLW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "204", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "v9kesNrWf280f" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rlKfWwpNKmYOuoJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7g9TKBPoM8gwTE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DFR5tMoC3v" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-302881895eae", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 72, + "prompt_tokens": 701, + "total_tokens": 773, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "yM4A1q422wS3s" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/3183b7beec7e4e89f8051a2aec67b4a1f3b48fb71f8682967d35e19498eb9386.json b/tests/integration/responses/recordings/3183b7beec7e4e89f8051a2aec67b4a1f3b48fb71f8682967d35e19498eb9386.json new file mode 100644 index 000000000..2a6d0fa2d --- /dev/null +++ b/tests/integration/responses/recordings/3183b7beec7e4e89f8051a2aec67b4a1f3b48fb71f8682967d35e19498eb9386.json @@ -0,0 +1,1901 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_filter_by_region[openai_client-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "What are the updates from the US region?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_gaVvfdNi1X9Ejqz6X9cirf8K", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Latest updates from the US\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_gaVvfdNi1X9Ejqz6X9cirf8K", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 2 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-247992711531, score: 0.0055330209977201275, attributes: {'region': 'us', 'category': 'engineering', 'date': 1680307200.0, 'filename': 'us_engineering_q2.txt', 'document_id': 'file-247992711531', 'token_count': 18.0, 'metadata_token_count': 32.0} (cite as <|file-247992711531|>)\nUS technical updates for Q2 2023. New features deployed in the US region.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-247992711530, score: 0.0030342058372720073, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-247992711530', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-247992711530|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Latest updates from the US\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xbgQU1pz8digKj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Y11SOVtDhizUA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " latest", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KONaORapM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " updates", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OTVgisCu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " from", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "F8fFCLXyF3s" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aZKc5kF6Izj0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EyOtxHnHCxT21" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GhX6z0sWt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " include", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cHRnB8Eu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6w6PFQi9bwVN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " deployment", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wNt8N" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dWLFRaAtoTtcf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " new", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hdKEemnii9Rc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " technical", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "a0rEaC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " features", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "63d1HW0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "k3gxfpDS91QOq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XSwz9dqUNC4lvR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "2", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gv7fw5ky6B5m8wm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MILBm1J6SSF8RI8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NufIjgz7sQDo0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2TUf8mnjobmAciQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ku47E3nyPnAzvT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WzFxI6InLRxrxQw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "90yxqSuELQdL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UISsAwWYh9eJMAw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "247", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "anMEhYBKfqdq6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "992", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gSex80SzbOxub" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "711", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3lWS69pM375sg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "531", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EMrWsOSsCUXFE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ba2pdxGvVL70MyB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "B5j8S4TtjCp7Lu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " Additionally", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jmh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7N9iUjFprpMKotf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qfwfzHA884WRM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ERZ3FMwTc9VYnV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fvctmbn442LEVlO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "r4sCuVkOSSBxaTp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hRLijcyHVt3zq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nYm9gYiPJCD29ay" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EnERakfsNavvF9L" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " there", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QWjVNGC1pY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " was", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AAZZ8y1vfM5s" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MwAQ5wkQCuLzfv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5Ez58wn4m95X1Wp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "15", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vn29orqNToIrHK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "%", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hxZ1OTjPnyewmVT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " increase", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fld3Vw0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "u5dfAIrqLfJHO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VllH83vd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " as", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "B8PYgitfJ9NYw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hWxCmDMnEBjWHW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " result", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rd3oiOusk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2JENcsF1FE45u" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GQjl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cmN3YM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9lO9rcO68XigRm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NOoKiyp1NLzDQ9A" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "B9pKjViMd1YQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Iag83CfqbuzyMfI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "247", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "see6vhPp8FGDv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "992", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SDttS5cHQrKRP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "711", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1G13JxtGAwVSX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "530", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "G3jMGWayv5LgO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QQ0UWwE65UEv6vJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bk3Z7Esd27vevH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lGxLL18UVY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3183b7beec7e", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 65, + "prompt_tokens": 467, + "total_tokens": 532, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "zmImLRoI8q9Bj" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/354405fd4255ae9210d875c30b8c9e00a75d79046a954e4c5858e36c4fbd70c5.json b/tests/integration/responses/recordings/354405fd4255ae9210d875c30b8c9e00a75d79046a954e4c5858e36c4fbd70c5.json new file mode 100644 index 000000000..49cc0dced --- /dev/null +++ b/tests/integration/responses/recordings/354405fd4255ae9210d875c30b8c9e00a75d79046a954e4c5858e36c4fbd70c5.json @@ -0,0 +1,925 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_sequential_file_search[openai_client-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_4ac6gxccWFxDvEl8BizY3BJw", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model number of experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_4ac6gxccWFxDvEl8BizY3BJw", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-528246887823, score: 0.01927231682811354, attributes: {'filename': 'test_sequential_file_search.txt', 'document_id': 'file-528246887823', 'token_count': 19.0, 'metadata_token_count': 11.0} (cite as <|file-528246887823|>)\nThe Llama 4 Maverick model has 128 experts in its mixture of experts architecture.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model number of experts\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cNAmgzguPKxzrT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EA42hQaqSv6Dl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " L", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BaXUa7hVjk5nx5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "lama", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Qtlt9e2mKNnd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4uMDzeUHI2m6BqK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "4", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wAiaIwGRcePCkSP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " Maver", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9wrgxL4SLF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "ick", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3LAZNfrT4P56F" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FQnWVVG3uk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " has", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QBV750ljlBuw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CvHO7IpkYl1t6WT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "128", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "t9yXtBtcAN2Ym" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nYeTyozH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "l5TEj9wVsDVVa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " its", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eqM279ge3tlP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " mixture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "adEY1TL0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AQUpfvABqhFSw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CW4Mdlfb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " architecture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0VM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lVhduxzervQNW2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jLw8pSzPx1Fpvdu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jNRy9leoYXdz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "T0aCg9vGAgtyyqX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "528", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pecAt4HBqHqgq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "246", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HLmt7RtQ5V2Ad" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "887", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nayq4hw8P8k8X" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "823", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PONv6LbvqDB6n" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OOocdPvPE66JCLe" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IoRrfOtEJevEyh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3v8gEWZUDD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-354405fd4255", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 29, + "prompt_tokens": 332, + "total_tokens": 361, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "Vn7WFfgLy7CQc" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/3aa2233e21470cd1c2667b6e4e31cf680d89b3b3c936882767e4500b0cf6d517.json b/tests/integration/responses/recordings/3aa2233e21470cd1c2667b6e4e31cf680d89b3b3c936882767e4500b0cf6d517.json new file mode 100644 index 000000000..b8ecdd13e --- /dev/null +++ b/tests/integration/responses/recordings/3aa2233e21470cd1c2667b6e4e31cf680d89b3b3c936882767e4500b0cf6d517.json @@ -0,0 +1,660 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_sequential_file_search[client_with_models-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "id": "call_FzhOmTdZThRndI5rSASPdAqr", + "function": { + "arguments": "", + "name": "knowledge_search" + }, + "type": "function" + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3cjx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "{\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7fk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "query", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "S" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\":\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "G" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "L", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OdWuY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "lama", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "l2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " ", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KaloW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "4", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HzeTK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " Maver", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "ick", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ceO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " model", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " number", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WI17fZQOl0jugmg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " of", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rQq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " experts", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SOIKMbAKjFhXxq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\"}", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gbX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "tool_calls", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bZLJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3aa2233e2147", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 24, + "prompt_tokens": 74, + "total_tokens": 98, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "R0oA3PanLpARhLY" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/3cc58466163409f7044471fb2a27413151487768ad8d178b4c1c766ebf757a48.json b/tests/integration/responses/recordings/3cc58466163409f7044471fb2a27413151487768ad8d178b4c1c766ebf757a48.json new file mode 100644 index 000000000..46158a0ac --- /dev/null +++ b/tests/integration/responses/recordings/3cc58466163409f7044471fb2a27413151487768ad8d178b4c1c766ebf757a48.json @@ -0,0 +1,1450 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_streaming_events[openai_client-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "What are the marketing updates?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_Vdxnbo2D8ds3BuKCon8XUt9P", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"marketing updates October 2023\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_Vdxnbo2D8ds3BuKCon8XUt9P", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 4 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-284290576316, score: 0.004140319532899986, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-284290576316', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-284290576316|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-284290576317, score: 0.004082999220108273, attributes: {'region': 'us', 'category': 'engineering', 'date': 1680307200.0, 'filename': 'us_engineering_q2.txt', 'document_id': 'file-284290576317', 'token_count': 18.0, 'metadata_token_count': 32.0} (cite as <|file-284290576317|>)\nUS technical updates for Q2 2023. New features deployed in the US region.\n" + }, + { + "type": "text", + "text": "[3] document_id: file-284290576318, score: 0.0040444179984006476, attributes: {'region': 'eu', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'eu_marketing_q1.txt', 'document_id': 'file-284290576318', 'token_count': 17.0, 'metadata_token_count': 32.0} (cite as <|file-284290576318|>)\nEuropean advertising campaign results for Q1 2023. Strong growth in EU markets.\n" + }, + { + "type": "text", + "text": "[4] document_id: file-284290576319, score: 0.002818876355005682, attributes: {'region': 'asia', 'category': 'sales', 'date': 1688169600.0, 'filename': 'asia_sales_q3.txt', 'document_id': 'file-284290576319', 'token_count': 17.0, 'metadata_token_count': 31.0} (cite as <|file-284290576319|>)\nAsia Pacific revenue figures for Q3 2023. Record breaking quarter in Asia.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"marketing updates October 2023\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nx9r4D69rcypWA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": "I", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "A4ZKGkPtv2Wwqyp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " couldn't", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "i2Vdx5Y" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " find", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fdW9EbykXqU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " specific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6chY1km" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " information", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dK6g" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " on", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4wmjbVkImgz0Z" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rRdBwM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " updates", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "821V5Shj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FuoY0c1SRhRT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " October", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UAtkaVUB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0nAgeoEbS83tVPl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XTFlUvexf6qXO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vGoyiJEkxg2e8aV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gWbneuF5WI4RuRW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " If", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7brhkLMJznzgk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nLtGTa3GbOL1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " are", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "d2pMwFmStIRJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " looking", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7OkqUapB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "e7VxYUK15ayF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " recent", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "n2ad1L6N4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aBjq14" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " trends", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PAtcZG4HR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " or", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "c7gbk7ZWS04MN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " specific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GxR9BDz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " campaign", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yvLyd0D" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " updates", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ysvSUk2r" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " from", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Z9CS6e61ydO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " this", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Eixc8cqhCMt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " period", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "djozNodvK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fIShJ8hZ5mEx2p3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " I", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "iXsDOto9eL2Xu8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " recommend", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hYLtEN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " checking", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yXpWOm8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " recent", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bJu5dQkiN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " industry", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8YpXBbr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " reports", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VcJy96vm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " or", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mFg5sjoMQhsKO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " news", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cgUn7xv07qK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " articles", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oewS46J" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wqnPVTmcDKwi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XbYtUitg7HE4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " most", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ayvl63ALzGx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " up", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "flFZZPrv2kJbB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": "-to", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LNGYbEWIaqAqk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": "-date", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cpr7cBlyclh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": " information", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SCyc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gPPWMTfaAVWFaJ0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Glc1dAhUHV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-3cc584661634", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 48, + "prompt_tokens": 708, + "total_tokens": 756, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "0gPDKH0ISn2VM" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/436039b9bd78d795fe43610ba51875025701bd363939f36299cf66846167b173.json b/tests/integration/responses/recordings/436039b9bd78d795fe43610ba51875025701bd363939f36299cf66846167b173.json new file mode 100644 index 000000000..51e086faf --- /dev/null +++ b/tests/integration/responses/recordings/436039b9bd78d795fe43610ba51875025701bd363939f36299cf66846167b173.json @@ -0,0 +1,660 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search[openai_client-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768-llama_experts]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "id": "call_UKFNZA0eSkL6fZHbs8ygBd5W", + "function": { + "arguments": "", + "name": "knowledge_search" + }, + "type": "function" + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZEDA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "{\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FWy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "query", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\":\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "A" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "L", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eg5pY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "lama", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "i3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " ", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MIUQE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "4", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PcKai" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " Maver", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "ick", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rZW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " model", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " number", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5efBkaSneq3MYiM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " of", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Xzt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " experts", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VAZ5PINoNf5uLg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\"}", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5kI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "tool_calls", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BvPC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-436039b9bd78", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 24, + "prompt_tokens": 74, + "total_tokens": 98, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "967FbyvY0943LNF" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/43f424df929f565d2255c6d491d4bd19d8b1e30993882dad557fbdb655c65149.json b/tests/integration/responses/recordings/43f424df929f565d2255c6d491d4bd19d8b1e30993882dad557fbdb655c65149.json new file mode 100644 index 000000000..9843deb0d --- /dev/null +++ b/tests/integration/responses/recordings/43f424df929f565d2255c6d491d4bd19d8b1e30993882dad557fbdb655c65149.json @@ -0,0 +1,586 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search[client_with_models-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768-llama_experts_pdf]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "id": "call_YkpKfL9mwbGk2BLqNDoaFrO0", + "function": { + "arguments": "", + "name": "knowledge_search" + }, + "type": "function" + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1mfS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "{\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "d4b" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "query", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "l" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\":\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "L", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JRCsr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "lama", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " ", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QMJkY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "4", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "scjuN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " Maver", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "ick", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ocj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " model", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " experts", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mo3wLXjk9CANvH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\"}", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "byy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "tool_calls", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8nAM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-43f424df929f", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 22, + "prompt_tokens": 74, + "total_tokens": 96, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "JFn10T2PhGSmfeW" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/456673fd514b80abfa8bb13c25acb9fa640daa3a1e1b5eef7a96863a592cc7fa.json b/tests/integration/responses/recordings/456673fd514b80abfa8bb13c25acb9fa640daa3a1e1b5eef7a96863a592cc7fa.json new file mode 100644 index 000000000..6d6913d5a --- /dev/null +++ b/tests/integration/responses/recordings/456673fd514b80abfa8bb13c25acb9fa640daa3a1e1b5eef7a96863a592cc7fa.json @@ -0,0 +1,1091 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search[openai_client-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768-llama_experts_pdf]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_M8gyYiB39MwYdJKc4aHIGbfA", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model number of experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_M8gyYiB39MwYdJKc4aHIGbfA", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 2 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-379221123213, score: 0.008294223190489081, attributes: {'filename': 'llama_stack_and_models.pdf', 'document_id': 'file-379221123213', 'token_count': 98.0, 'metadata_token_count': 11.0} (cite as <|file-379221123213|>)\n, \nhardware\n \nvendors,\n \nand\n \nAI-focused\n \ncompanies)\n \nthat\n \noffer\n \ntailored\n \ninfrastructure,\n \nsoftware,\n \nand\n \nservices\n \nfor\n \ndeploying\n \nLlama\n \nmodels.\n \nLlama 4 Maverick \n Llama 4 Maverick is a Mixture-of-Experts (MoE) model with 17 billion active parameters and 128 experts. \n" + }, + { + "type": "text", + "text": "[2] document_id: file-379221123213, score: 0.0033899234401598543, attributes: {'filename': 'llama_stack_and_models.pdf', 'document_id': 'file-379221123213', 'token_count': 498.0, 'metadata_token_count': 11.0} (cite as <|file-379221123213|>)\nLlama Stack \nLlama Stack Overview \nLlama Stack standardizes the core building blocks that simplify AI application development. It codifies best \npractices\n \nacross\n \nthe\n \nLlama\n \necosystem.\n \nMore\n \nspecifically,\n \nit\n \nprovides\n \u25cf Unified API layer for Inference, RAG, Agents, Tools, Safety, Evals, and Telemetry. \u25cf Plugin architecture to support the rich ecosystem of different API implementations in various \nenvironments,\n \nincluding\n \nlocal\n \ndevelopment,\n \non-premises,\n \ncloud,\n \nand\n \nmobile.\n \u25cf Prepackaged verified distributions which offer a one-stop solution for developers to get started quickly \nand\n \nreliably\n \nin\n \nany\n \nenvironment.\n \u25cf Multiple developer interfaces like CLI and SDKs for Python, Typescript, iOS, and Android. \u25cf Standalone applications as examples for how to build production-grade AI applications with Llama \nStack.\n \nLlama Stack Benefits \n\u25cf Flexible Options: Developers can choose their preferred infrastructure without changing APIs and enjoy \nflexible\n \ndeployment\n \nchoices.\n \u25cf Consistent Experience: With its unified APIs, Llama Stack makes it easier to build, test, and deploy AI \napplications\n \nwith\n \nconsistent\n \napplication\n \nbehavior.\n \u25cf Robust Ecosystem: Llama Stack is already integrated with distribution partners (cloud providers, \nhardware\n \nvendors,\n \nand\n \nAI-focused\n \ncompanies)\n \nthat\n \noffer\n \ntailored\n \ninfrastructure,\n \nsoftware,\n \nand\n \nservices\n \nfor\n \ndeploying\n \nLlama\n \nmodels.\n \nLlama 4 Maverick \n Llama 4 Maverick is a Mixture-of-Experts (MoE) model with 17 billion active parameters and 128 experts. \n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model number of experts\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SwfFM0srbgssjN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TMGpD5yrMcsaA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " L", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hahFDk4feSTCWP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "lama", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "95LWXZ3gscj3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8e1alI9PtPWeh4N" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "4", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pXcHEjkUvIkiPIc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " Maver", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZBfIZFS72Y" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "ick", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6j7v1RfeXAKuX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "n98X3HtSR3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PwXBDEpj60QVV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AydGbRLA6VQmbT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " Mi", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "67go56fuzMfjs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "xture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2qYVzlf84GT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "-of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xLePcKPzOicKY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PlAV9kCmVSJFdei" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "Experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1s7VSQ4bj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " (", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KpX0NqaWcNx8lF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "Mo", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lhWajHou1GuZDs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "E", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BQNIB9NDUPeCqDv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": ")", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CBPR5MhECVN8z6S" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "J1EB8maIVK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " with", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oXfyN6XnE2I" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VUJFkglZr6NoMj0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "128", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rfc9ULZD1ePOC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ES9e0JOf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jtSBYNEQUwIk4w" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VYWqZdmqVE9ASfF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "P41vqRnJjMXs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Byy12tOEJNEzC0i" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "379", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "t3NQ6wh9nJOYp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "221", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VtpvQPfa7bckm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "123", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8nUw5oqI3pe5g" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "213", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7Fmiy7C0pi2oJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8iORdw4bWjrxjzO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5iskgj0JKopJ9a" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "18czcgOzOS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-456673fd514b", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 35, + "prompt_tokens": 992, + "total_tokens": 1027, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "Xswh7p7QTKmf" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/48cda1e432d9f9c3ce773147998fe5621478e542632f882fee067fd068c410dd.json b/tests/integration/responses/recordings/48cda1e432d9f9c3ce773147998fe5621478e542632f882fee067fd068c410dd.json new file mode 100644 index 000000000..21162c632 --- /dev/null +++ b/tests/integration/responses/recordings/48cda1e432d9f9c3ce773147998fe5621478e542632f882fee067fd068c410dd.json @@ -0,0 +1,1834 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_sequential_file_search[openai_client-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_4ac6gxccWFxDvEl8BizY3BJw", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model number of experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_4ac6gxccWFxDvEl8BizY3BJw", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-528246887823, score: 0.01927231682811354, attributes: {'filename': 'test_sequential_file_search.txt', 'document_id': 'file-528246887823', 'token_count': 19.0, 'metadata_token_count': 11.0} (cite as <|file-528246887823|>)\nThe Llama 4 Maverick model has 128 experts in its mixture of experts architecture.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model number of experts\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + }, + { + "role": "assistant", + "content": "The Llama 4 Maverick model has 128 experts in its mixture of experts architecture <|file-528246887823|>." + }, + { + "role": "user", + "content": "Can you tell me more about the architecture?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_rmMfpryevUEhVly9yXhlsVG0", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model architecture details\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_rmMfpryevUEhVly9yXhlsVG0", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-528246887823, score: 0.005821830799489026, attributes: {'filename': 'test_sequential_file_search.txt', 'document_id': 'file-528246887823', 'token_count': 19.0, 'metadata_token_count': 11.0} (cite as <|file-528246887823|>)\nThe Llama 4 Maverick model has 128 experts in its mixture of experts architecture.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model architecture details\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eOzeWuuyzb1Cax" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "I", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "y0Y8odXG9qdUe7I" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " couldn't", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EcimOlX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " find", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2xoX1Mfyt2k" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " any", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6N4ypYmL22bj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " additional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tXBaT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " information", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ucy0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " specifically", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WMb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " about", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JMLc0qNW7U" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PGuTOoueNkNj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " architecture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "758" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wTolxcHFQFnhy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XXWkZBijjiRl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " L", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ENxaVZp29TKmrQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "lama", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GcRsklIKy7uc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AkhqMJI2vVCTa87" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "4", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "18zmzdHXdV17dS0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " Maver", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aJCGfZTdv7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "ick", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yKOqRBtVIHg8C" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0wLo48R9fN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " beyond", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wOrIhrEjy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " it", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zjl5lQZMpNEQy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " having", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fHiQTRhsZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SyRu2cUUzWw0dSR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "128", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "krUOaeWWs0nTm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "53ciIATg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "O7TA3jGRi5gOK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " its", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eVRuQvfCo6jZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " mixture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NgLWPDUG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6hmxppafQG3w7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "y0edqNvN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " architecture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IXI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8ZFgOgkQUr0KHG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "F2x2Fxv2PW85Ntr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "X1kLNcc12pxW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "q9Pz4rdZGASZqnL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "528", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nmto1jiHrMUGs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "246", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zOweP5LmiAtRH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "887", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fN5DDNzmCM8HQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "823", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qXtEXESLuSvKj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9tBrTzR3kDTCVpQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OlfqU2ckEurvkS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " If", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lt0DqkfjL7iWa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MjoezndWRWvB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " have", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SC3tCh87hus" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " more", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1r2cYBoAOF4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " specific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RdMKcy9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " aspects", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Tf5cQpGn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tPePnPjTkt9CC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Wkhuo2lcuAtf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " architecture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qGD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "e9WcLaE3hPnb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " are", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wrCPIgJbUCrs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " interested", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pJiej" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NHsi65VAY35Eu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kLk2gXY4LnU07wr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " please", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sS4rWhZAr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " let", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xTgqSZ5RDY7F" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " me", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Vf8BNUHLXCp14" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": " know", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8WYGLMZP5AU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": "!", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BTg7xFpysmTHZuI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "p0Ql9TrOAI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-48cda1e432d9", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 61, + "prompt_tokens": 633, + "total_tokens": 694, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "A8Hnqa5510Usq" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/5c9b18529d9400f8992d48eb3204e1ad41226bd16bdac187a98b591ea219062f.json b/tests/integration/responses/recordings/5c9b18529d9400f8992d48eb3204e1ad41226bd16bdac187a98b591ea219062f.json new file mode 100644 index 000000000..62a8fcff1 --- /dev/null +++ b/tests/integration/responses/recordings/5c9b18529d9400f8992d48eb3204e1ad41226bd16bdac187a98b591ea219062f.json @@ -0,0 +1,668 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_sequential_file_search[client_with_models-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_FzhOmTdZThRndI5rSASPdAqr", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model number of experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_FzhOmTdZThRndI5rSASPdAqr", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-797509666839, score: 0.01927231682811354, attributes: {'filename': 'test_sequential_file_search.txt', 'document_id': 'file-797509666839', 'token_count': 19.0, 'metadata_token_count': 11.0} (cite as <|file-797509666839|>)\nThe Llama 4 Maverick model has 128 experts in its mixture of experts architecture.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model number of experts\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + }, + { + "role": "assistant", + "content": "The Llama 4 Maverick model has 128 experts in its mixture of experts architecture <|file-797509666839|>." + }, + { + "role": "user", + "content": "Can you tell me more about the architecture?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "id": "call_0ABjXmEaManGBvCYVZD4QgMt", + "function": { + "arguments": "", + "name": "knowledge_search" + }, + "type": "function" + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "4WCi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "{\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "xZw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "query", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "v" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\":\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "z" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "L", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "pxc1l" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "lama", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "rw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " ", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "1uQsI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "4", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "3GUgc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " Maver", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "ick", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "iSJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " model", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " architecture", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "PBkDU4h5O" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " details", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "FhjYMfvqXEQemh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\"}", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "bJM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "tool_calls", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": null, + "obfuscation": "SZTO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5c9b18529d94", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_65564d8ba5", + "usage": { + "completion_tokens": 23, + "prompt_tokens": 377, + "total_tokens": 400, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "aghfgDFthkUtG" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/5d8c5aed931209aeeaa35ead5654389f7ed38381807ba34956844352a35db706.json b/tests/integration/responses/recordings/5d8c5aed931209aeeaa35ead5654389f7ed38381807ba34956844352a35db706.json new file mode 100644 index 000000000..ac2d20fdf --- /dev/null +++ b/tests/integration/responses/recordings/5d8c5aed931209aeeaa35ead5654389f7ed38381807ba34956844352a35db706.json @@ -0,0 +1,1843 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_filter_compound_and[openai_client-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "What are the engineering updates from the US?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_cpbC1lb0MlCcVyxpYT10GvpE", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"engineering updates United States October 2023\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_cpbC1lb0MlCcVyxpYT10GvpE", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-90357487492, score: 0.00660655550631643, attributes: {'region': 'us', 'category': 'engineering', 'date': 1680307200.0, 'filename': 'us_engineering_q2.txt', 'document_id': 'file-90357487492', 'token_count': 18.0, 'metadata_token_count': 32.0} (cite as <|file-90357487492|>)\nUS technical updates for Q2 2023. New features deployed in the US region.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"engineering updates United States October 2023\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zQkkxhoeujkc7P" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "I", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2xaSzeY7yKDrKpg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " couldn't", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "en9p5ol" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " find", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TOfMFx6hfEx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " specific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3P539nE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " engineering", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "y4Bs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " updates", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "q1nDvqTq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " from", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wwwrhuEfHUX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hku7xlCFCPJX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CxO8KS2OSYV7K" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "l37B1YQNaVuP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " October", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OkU6tibY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QUJwQ2QMGQ7lBwi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xSMBPQ9YphrsO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YLjDf5RqAwAU8v6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fE88WBjGT2JuX5c" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " However", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1FZU2zRa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VtB4pZrnTfMQS0a" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " there", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2osTTy3Acl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " were", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NWt4foJGaDd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " technical", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VuknOG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " updates", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4Fg28gZO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " and", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NIrc5VEw2dn9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " new", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eLlxZ1TV3SY8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " features", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mKY5mcI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " deployed", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zrSUS7W" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "K588szoBe2CWG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nPKpJVDcCGOq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wdiO002WOCZMw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dBI9C2EaJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YXDJrAoM2xpn3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nbHskKzSk5Tn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " second", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xosvMX9WT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " quarter", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "casRFW5t" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2833DB7wHte62" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xZMH8EG1VcVUI05" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DNba0WYBfOB63" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "D10nFyYjOBtDhNB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SiBpzADVPzyPLB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gSFXtcS2xJrLrBn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9sb7koE3Ibmp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YTRbcGX5qHRIum0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "903", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VB4Wnn3wnB5rQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "574", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "n7OUR9hI5aIZW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "874", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "uTb0mzQGzZ7NC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "92", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Eg5vmUYKY4dYK3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LvKzyCi1SJ2eHvw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DNnVQcFXnZetlF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " Please", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LBkXQasfC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " let", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "U1XMN0DtNVNt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " me", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Aaw7bepHICtY9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " know", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "man35BruyNc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " if", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6sAVmPIjOkr00" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MIFWy91OAmYs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " want", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cfHX0lSqxUO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " more", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YcdaojiiLrg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " detailed", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BP5KY9N" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " search", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Py4nUtGu0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " results", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wdB7whVM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " or", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0fMWivMMJdj6S" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " specific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4p8vWkE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": " dates", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ACCKnnDEJm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nEFmjSyYEL4C7m5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jdU4yQikwA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-5d8c5aed9312", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 63, + "prompt_tokens": 345, + "total_tokens": 408, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "WoKxnDwdUb8AK" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/7437ac7a1debcb3fb24b24eff26a26d16cd34bf338c9843ca8f9d5ce92101d72.json b/tests/integration/responses/recordings/7437ac7a1debcb3fb24b24eff26a26d16cd34bf338c9843ca8f9d5ce92101d72.json new file mode 100644 index 000000000..24837e75c --- /dev/null +++ b/tests/integration/responses/recordings/7437ac7a1debcb3fb24b24eff26a26d16cd34bf338c9843ca8f9d5ce92101d72.json @@ -0,0 +1,925 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_sequential_file_search[client_with_models-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_FzhOmTdZThRndI5rSASPdAqr", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model number of experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_FzhOmTdZThRndI5rSASPdAqr", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-797509666839, score: 0.01927231682811354, attributes: {'filename': 'test_sequential_file_search.txt', 'document_id': 'file-797509666839', 'token_count': 19.0, 'metadata_token_count': 11.0} (cite as <|file-797509666839|>)\nThe Llama 4 Maverick model has 128 experts in its mixture of experts architecture.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model number of experts\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vt3GstRZ0aEOtQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "V8LCLbwuWE6zL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " L", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AE5LGiL5P2vkSi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "lama", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "URAGF9HPepld" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YhQyLMSQQBttHSZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "4", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MTXfd73x6CxT4jC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " Maver", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FRyNMsTqpf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "ick", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pEvb1BhfCzIu3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ti8cCbCXCN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " has", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ePgYRhIsTnxM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Er6jdeAhYhP5yZo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "128", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kKbskZOW0nnLX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9EkfQIUH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "s9t2OgQMO8lpH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " its", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Y5meY2O4Ow06" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " mixture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "d8vzlOjF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BZ0ZP2N8lYwx9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GLsfkS8o" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " architecture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3le" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6yIln93VE6CXZc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "12h0ytbne30ZcjD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0EYqrf9KJNnT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9ZNIDg7zELT5q61" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "797", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IGDExcadNKQ6z" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "509", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "36Ncp9snNGK23" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "666", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oVuXPzQ3kvZIK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "839", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZIqozh3gNXBtg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "j1xdaBLDmWec5Fo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "057ZL7KuQlBsN5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Mizb7MVtEE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-7437ac7a1deb", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 29, + "prompt_tokens": 332, + "total_tokens": 361, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "p2sRYaAtwLWB8" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/8d5e85fc1c0a827552218dceb170769d3809b1c271b0e1baaa182d8b01ad8571.json b/tests/integration/responses/recordings/8d5e85fc1c0a827552218dceb170769d3809b1c271b0e1baaa182d8b01ad8571.json new file mode 100644 index 000000000..da0e36323 --- /dev/null +++ b/tests/integration/responses/recordings/8d5e85fc1c0a827552218dceb170769d3809b1c271b0e1baaa182d8b01ad8571.json @@ -0,0 +1,1550 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_filter_by_date_range[client_with_models-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "What happened in Q1 2023?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_9VwRE1rGyuqq0lSoaOwqpufL", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Q1 2023 events\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_9VwRE1rGyuqq0lSoaOwqpufL", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 2 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-664068282484, score: 0.003343484460164191, attributes: {'region': 'eu', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'eu_marketing_q1.txt', 'document_id': 'file-664068282484', 'token_count': 17.0, 'metadata_token_count': 32.0} (cite as <|file-664068282484|>)\nEuropean advertising campaign results for Q1 2023. Strong growth in EU markets.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-664068282482, score: 0.003225665460848446, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-664068282482', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-664068282482|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Q1 2023 events\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xd1EWvG6Br7Mcu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "In", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "21AlcSbxTO2NI0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aZgCL6JG8N9qZT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZzfpP90mVCB5zkf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eeJiipF7y4uae9b" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5ZicAj0XS63mP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xFWsbGuSPpp3CP8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YebpJFCkNQtXTbc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " there", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "m6onZvh1zo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " was", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GraxfuUTykoe" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " strong", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ktLD6juI9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " growth", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "N1hMwY8uv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ErUAc22ysLHKJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " European", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Hc76PzZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " advertising", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "u5i7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6Nww0q" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " and", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Rf4bxmgcX1T6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lXMjz3QMliBIE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YwcM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NiXjBs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " resulted", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QqspTfz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8ii7vh2Jb7Ylx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JiWbPj2MRLeoKA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "348XQmrHiPQxofQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "15", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kAeKzShFT2WSiQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "%", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OoyfjAD8Z9yBlHP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " increase", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fWb5eLD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sobgcicZCvevA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AaEaIOVK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3LUwfzE4bKzeB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QLFqMwueqIXb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jaemHOrdklq9X" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "iz0HAKWpi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fNevow6v8az7u0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qs9rTyPemvjiu9g" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4HofZYdLTfhz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2y8Leo6hU70iMrC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "664", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rSjz9TEnMeUY4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "068", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4wkVg4aYwIh0W" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "282", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vDoQXY7ktZ6Lt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "484", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sc96nstSQzCUX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hEAbpk0WmMMcOOq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "><", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TiabYQfNL2DXNi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "x6DEcbivhm7XICE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "O25Jkg2FWWPI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Jn7sXN7Pn4hZt7B" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "664", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eF7eob56ddmSj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "068", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "A0H55G1XICkmB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "282", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4jdbPjqHim9R3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "482", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "i5OLbmY5H9Cqk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZU4vVlx7O6c55qE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "P5rydlYeSWFjpd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NlruXH6LVI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-8d5e85fc1c0a", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 52, + "prompt_tokens": 466, + "total_tokens": 518, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "KpIKP0E7E94PM" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/a37a1c209697b900177f10ec5348b0ced3394322927971a2f4dfe52c2768ce57.json b/tests/integration/responses/recordings/a37a1c209697b900177f10ec5348b0ced3394322927971a2f4dfe52c2768ce57.json new file mode 100644 index 000000000..e06bfaba7 --- /dev/null +++ b/tests/integration/responses/recordings/a37a1c209697b900177f10ec5348b0ced3394322927971a2f4dfe52c2768ce57.json @@ -0,0 +1,660 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_sequential_file_search[openai_client-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "id": "call_4ac6gxccWFxDvEl8BizY3BJw", + "function": { + "arguments": "", + "name": "knowledge_search" + }, + "type": "function" + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KVv4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "{\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "07x" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "query", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\":\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "L", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WQVqQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "lama", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "b5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " ", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5cG73" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "4", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0TZwr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " Maver", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "ick", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "70V" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " model", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " number", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tgfI6t9sl0qk9lj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " of", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bb4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " experts", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YwrLoyA0SH8QKR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\"}", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "r2N" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "tool_calls", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UcRX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a37a1c209697", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 24, + "prompt_tokens": 74, + "total_tokens": 98, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "Z9OHDBA6RWfdcqi" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/a9af62eaeb01f80a9b09b7c7ba468e6a34945cbf0b12aa2c74b2caedc31a821f.json b/tests/integration/responses/recordings/a9af62eaeb01f80a9b09b7c7ba468e6a34945cbf0b12aa2c74b2caedc31a821f.json new file mode 100644 index 000000000..0cb8ac7e7 --- /dev/null +++ b/tests/integration/responses/recordings/a9af62eaeb01f80a9b09b7c7ba468e6a34945cbf0b12aa2c74b2caedc31a821f.json @@ -0,0 +1,2198 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_filter_by_date_range[openai_client-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "What happened in Q1 2023?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_a6TuAAAmLcfVWfz4H3VriVLv", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"key events in Q1 2023\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_a6TuAAAmLcfVWfz4H3VriVLv", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 2 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-151637398237, score: 0.0034820368215192597, attributes: {'region': 'eu', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'eu_marketing_q1.txt', 'document_id': 'file-151637398237', 'token_count': 17.0, 'metadata_token_count': 32.0} (cite as <|file-151637398237|>)\nEuropean advertising campaign results for Q1 2023. Strong growth in EU markets.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-151637398235, score: 0.0033373451138519685, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-151637398235', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-151637398235|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"key events in Q1 2023\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FUOfxQCJpoN8Ac" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "In", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JtCuvuKyUbrAbt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qhTUHTQlrwXU0U" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "y6wJsX0ap4QbHGG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OL0uTkEU8cMZPdo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0mlyebdjO9iCj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "95RQ1BybFVEeOc7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OWKlQBEZkc0wsq2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " there", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CZLdJybw0Q" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " was", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WpFn07JrgbOg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " strong", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GSeDlgHdp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " growth", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2SvXL4cDz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hHJYKNb0ZPFgV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " European", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zpuFDkz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " advertising", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mDdd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QbGZOR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yNhvDFVl7tilGHa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " suggesting", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OEz5p" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kdgTe5OLeAnYdy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " positive", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hV7VamL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " trend", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "n2v0HSlXjg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZFKtQB6USHuMl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " EU", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AFIDIU9dGQJ4x" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " markets", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "iioEXzYK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qU8d2pPUEKgKCD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IaWnnKBiO6Qf5zb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PI3GH5WJDsv9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rxRdxUoXHnSzq8i" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "151", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EM1PtY9vLHHky" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "637", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9GooWUHnQ2qAt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "398", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IyiDkF20T3skQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "237", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zonKkqaKIjMs9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vhBMsoF9J6vJfrA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JVo6EBdPXaSJig" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " In", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "H2fKEeiz7VPy8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wnvgMjFFaXfw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " United", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JnJ8KCmzx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " States", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yg0qYoQao" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LzHxTwJb3TGqFY4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3qGu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UfofNg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " led", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IPIyv1PEcg7H" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " to", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xylH74SZS0Z2e" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JpLXyQASFCMrri" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "k35I1FSYjVTvDdD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "15", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MfsreCLZy22ePz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "%", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kAc78c4crPTx9ti" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " increase", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xaRO1oN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vdkXj3BS1GN8g" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "t2R31Xot" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Vhcv7FZZikNgpC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WUltM5F05EgHUlJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "e6Q0E3SMLHNp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Hu3MiziaqEvcdAf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "151", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XWaYLY8lCPPRk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "637", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sx9VOmWIA58h5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "398", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cSbrZOxDOWsjS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "235", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "S02wAL3Ay31YZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "clIJQS8VeawXpEf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "e6bAxu9n9Q6rMb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " These", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mRjmT3yB3U" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " outcomes", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pwNNj8y" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " reflect", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "STnse8g6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " significant", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "73uD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " developments", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IW1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SeTmIBQHq8bhH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ye2Ql05U9OfQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LXwQyM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " sector", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "97Veivzyv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Y8pwna8zJhjG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " both", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "iyB99YAAwT5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " regions", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EahPYT2z" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " during", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nRmQF4TI8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " this", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nNHLBxmmnaX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": " period", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TvtyJSr8F" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fh4z4XUNWx0FkjJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "73H8Ymm9DP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-a9af62eaeb01", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 76, + "prompt_tokens": 472, + "total_tokens": 548, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "zkIB1oeGf8c62" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/b088ac3381c34089cf0eaba5d4b922271e8f8e8f169d94c5505de2a3ebe69c47.json b/tests/integration/responses/recordings/b088ac3381c34089cf0eaba5d4b922271e8f8e8f169d94c5505de2a3ebe69c47.json new file mode 100644 index 000000000..1b58212cb --- /dev/null +++ b/tests/integration/responses/recordings/b088ac3381c34089cf0eaba5d4b922271e8f8e8f169d94c5505de2a3ebe69c47.json @@ -0,0 +1,763 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search[client_with_models-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768-llama_experts]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_gZXRKN1HMDC16NP9wNPAkP9K", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model experts count\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_gZXRKN1HMDC16NP9wNPAkP9K", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-864460993305, score: 0.011418757438261288, attributes: {'filename': 'test_response_non_streaming_file_search.txt', 'document_id': 'file-864460993305', 'token_count': 10.0, 'metadata_token_count': 13.0} (cite as <|file-864460993305|>)\nLlama 4 Maverick has 128 experts\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model experts count\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mdcAUKOPQatFDX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SXcyzIHM4JAb9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": " L", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tIP37AbLRJtgw3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "lama", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "T6hl8O1yALrY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EXmrHS7V452DM8U" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "4", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WtvMno5JF3BbJja" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": " Maver", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wasA4Ibq0N" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "ick", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zC5PHOZiqE8hV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TCLUWLK9fl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": " has", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "p1X5NlNo8vvP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "B4xarQa3WvzzZke" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "128", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BEDzpnch9VTi5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NbeiTxmO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oEzJnEJlvJlvVB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "COTg5EQAvBoF1X4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "agnuCzlpfNMe" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6VItAaWcjjp8PCq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "864", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IG901zUD4iD52" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "460", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dTfo3F1G4iNgN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "993", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1hexBY3sKrN92" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "305", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "z2dp3INsqrUxD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Dt8q83oqrxwR8j6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ALKi5zh4iadh4W" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "j7ONgCjwww" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b088ac3381c3", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 23, + "prompt_tokens": 324, + "total_tokens": 347, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "frqCbYK1PAWId" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/b2d4b49b6d354fb75745d0b2ad461dac007bb6afa191350b03077eb71c316c61.json b/tests/integration/responses/recordings/b2d4b49b6d354fb75745d0b2ad461dac007bb6afa191350b03077eb71c316c61.json new file mode 100644 index 000000000..021aa70e4 --- /dev/null +++ b/tests/integration/responses/recordings/b2d4b49b6d354fb75745d0b2ad461dac007bb6afa191350b03077eb71c316c61.json @@ -0,0 +1,623 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search[client_with_models-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768-llama_experts]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "id": "call_gZXRKN1HMDC16NP9wNPAkP9K", + "function": { + "arguments": "", + "name": "knowledge_search" + }, + "type": "function" + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "iVfJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "{\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "F4s" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "query", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "n" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\":\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "m" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "L", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Q90JJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "lama", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "e6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " ", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RVjmv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "4", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fxip1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " Maver", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "ick", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "APw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " model", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " experts", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SGxrR0wH4r9xmj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " count", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\"}", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DPW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "tool_calls", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pWLu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b2d4b49b6d35", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 23, + "prompt_tokens": 74, + "total_tokens": 97, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "AQxCe0R2ppw6hGr" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/b3e7d7ee61c61b858b8a5f6af016e26bc3f948640354c1210f02c3b63bd26a55.json b/tests/integration/responses/recordings/b3e7d7ee61c61b858b8a5f6af016e26bc3f948640354c1210f02c3b63bd26a55.json new file mode 100644 index 000000000..ec816c876 --- /dev/null +++ b/tests/integration/responses/recordings/b3e7d7ee61c61b858b8a5f6af016e26bc3f948640354c1210f02c3b63bd26a55.json @@ -0,0 +1,2522 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_filter_by_category[openai_client-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "Show me all marketing reports" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_oijotTqrVfTYc1H7Ty7OAMHx", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"marketing reports\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_oijotTqrVfTYc1H7Ty7OAMHx", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 2 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-824569833174, score: 0.0027636340573366355, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-824569833174', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-824569833174|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-824569833176, score: 0.0025355615447054444, attributes: {'region': 'eu', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'eu_marketing_q1.txt', 'document_id': 'file-824569833176', 'token_count': 17.0, 'metadata_token_count': 32.0} (cite as <|file-824569833176|>)\nEuropean advertising campaign results for Q1 2023. Strong growth in EU markets.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"marketing reports\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cos6THa2ZX2KuU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "I", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fZWSFgk1Wuv4xA7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " found", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "07DSnJFHoj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " two", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "V6ZMAXclTLwu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7oOKrE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " reports", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "trWMCEEC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": ":\n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OxyIyP7u2Ob" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "r2RZSdLmE80CNIG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yJvOtk4cU4VUUlb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3Oyep6T6FRdaz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6BBhoQizlwv7m7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " Region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Q5iXHjeXj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": ":**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mS75FlBS3PoNC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " This", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2wNojM7VjGw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " report", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Y8xa7BkEU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " focuses", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "W4FilnFr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " on", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mAuy2OnOvwKqh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YnRs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "secdWb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eYAu4NW47CVM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VC7kv2aFDsX83n" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BrOd6C1yPMX8FOM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qFSCWcv23GRdyza" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fuaXbYk7cEVxV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "q14il9Icry8ur4W" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9c1sbULtapcYo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "23VcgXbVznMI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ce8ZiEMyhaZ81" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qYfmmBPJeAGzp4K" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " where", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rFDP6ez75f" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oZ2hPrbE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " increased", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QTljTl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " by", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "R5GyjiHFskMh3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "358zKwoy9IgLkgs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "15", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SySLcX59fdcAPY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "%", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gaHrAcd9DrrG4wy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vDwGEi7dPEs1IU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eGeq8xRIQsvazAu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sim7a6Q5hoSi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PDuli1x9NTHNzEv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "824", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0Dqig36ctmcCn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "569", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PY9ad2KqxevuT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "833", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OZ4s2XeYs9Yxo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "174", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "V8JXGZVplbGuY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TvG7WEQ7sORVuqp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": ">", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bcesVvHFUALcMJz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": ".\n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AycX7Q2TJgB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "2", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KkzDaxk9seUS8RO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "p5qMyuMSlGwwubs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mwzU5jL6IckFr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "European", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "appU9xQA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " Region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OPBHPOt0K" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": ":**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BZPqcPd67QKyp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " This", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zUaUaNeDfFo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " report", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ELstnCvfT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " details", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1CgWNiyE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "09bpzjp2bEks" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " results", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ogm9r5X1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mvCjxDOvHpxbi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " advertising", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FIJ4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kcvMCY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LcB85y37trMdZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WS5xOmUygAD8wd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8Q5OzwSoBcjCmdh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Jxb4XJIyOWLMWlC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OCLlLpIv6srSx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6sq5GC8JM5ZNmLl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CG9PkggQdi0n" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kNv92G9b6sUh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " European", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RC0MI0D" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " markets", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9rn0MKS5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rypVA1w8HQvBKYz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " citing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qmlWXMuo3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " strong", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "I5dMeVX52" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " growth", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "y4l1qzJ15" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DohbrYLnknoSJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5BDnaJfP7aPB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Xcav3jUhA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Vaaw6gdZ1gb5Rc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kpNQt9js5lcD0zF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hrZzbD1OTBPG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0St3B7u13lxZYQZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "824", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "12k4Iqmp2C94u" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "569", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qSU6y1yxLUuym" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "833", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lDT1VP4FOH4pi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "176", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ua1xbGW5Ap5Dp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8QDWL2sDP9fj1ax" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jjCpaZiSRYkhQE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VXUdovY5BC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b3e7d7ee61c6", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 88, + "prompt_tokens": 456, + "total_tokens": 544, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "SkreRidbyd2WQ" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/b43291ac9074915996cd682cd023ce83993fb0b178ad02cb989e90ada09bdc1d.json b/tests/integration/responses/recordings/b43291ac9074915996cd682cd023ce83993fb0b178ad02cb989e90ada09bdc1d.json new file mode 100644 index 000000000..75434eeae --- /dev/null +++ b/tests/integration/responses/recordings/b43291ac9074915996cd682cd023ce83993fb0b178ad02cb989e90ada09bdc1d.json @@ -0,0 +1,705 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search_empty_vector_store[openai_client-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_ltsd3q9G7fq4by5VmgdvtNRX", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model number of experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_ltsd3q9G7fq4by5VmgdvtNRX", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 0 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model number of experts\". Use them as supporting information only in answering this query.\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0fgBVqnoZphRrO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": "I", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kAndkfubV6NKXsY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " couldn't", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EXhAPDe" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " find", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nrXymFqvjdq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " specific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lajtruZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " information", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xasK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " on", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mrqUvzsWBTOO8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ha2tJcKUNTiA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " number", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vpCsuweOe" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GFFxLjDCZduzC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Xs8Vo94R" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qLbADKniURbG3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YF79Ocjj7FyP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " L", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pyuKZULeLEPvik" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": "lama", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UKwrHwSz4E7a" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GRGchsnIuihqbZ0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": "4", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Qpq01eD86BDpBoj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " Maver", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZbaWcRhys3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": "ick", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "srlQAcwr3TFz2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OaURzdjGvn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "I81L6v0mjvIsSpW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eCBzPYMI2j" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b43291ac9074", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 21, + "prompt_tokens": 163, + "total_tokens": 184, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "hPWaHWTF4MLy7" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/b46a06f7d0c1fde007c2b9e6e6d0b4c0694dccd4c61731db54c2d06bad1a0098.json b/tests/integration/responses/recordings/b46a06f7d0c1fde007c2b9e6e6d0b4c0694dccd4c61731db54c2d06bad1a0098.json new file mode 100644 index 000000000..3014d416c --- /dev/null +++ b/tests/integration/responses/recordings/b46a06f7d0c1fde007c2b9e6e6d0b4c0694dccd4c61731db54c2d06bad1a0098.json @@ -0,0 +1,1091 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search[client_with_models-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768-llama_experts_pdf]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_YkpKfL9mwbGk2BLqNDoaFrO0", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_YkpKfL9mwbGk2BLqNDoaFrO0", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 2 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-156847829497, score: 0.007500206285428307, attributes: {'filename': 'llama_stack_and_models.pdf', 'document_id': 'file-156847829497', 'token_count': 98.0, 'metadata_token_count': 11.0} (cite as <|file-156847829497|>)\n, \nhardware\n \nvendors,\n \nand\n \nAI-focused\n \ncompanies)\n \nthat\n \noffer\n \ntailored\n \ninfrastructure,\n \nsoftware,\n \nand\n \nservices\n \nfor\n \ndeploying\n \nLlama\n \nmodels.\n \nLlama 4 Maverick \n Llama 4 Maverick is a Mixture-of-Experts (MoE) model with 17 billion active parameters and 128 experts. \n" + }, + { + "type": "text", + "text": "[2] document_id: file-156847829497, score: 0.0032793168757021015, attributes: {'filename': 'llama_stack_and_models.pdf', 'document_id': 'file-156847829497', 'token_count': 498.0, 'metadata_token_count': 11.0} (cite as <|file-156847829497|>)\nLlama Stack \nLlama Stack Overview \nLlama Stack standardizes the core building blocks that simplify AI application development. It codifies best \npractices\n \nacross\n \nthe\n \nLlama\n \necosystem.\n \nMore\n \nspecifically,\n \nit\n \nprovides\n \u25cf Unified API layer for Inference, RAG, Agents, Tools, Safety, Evals, and Telemetry. \u25cf Plugin architecture to support the rich ecosystem of different API implementations in various \nenvironments,\n \nincluding\n \nlocal\n \ndevelopment,\n \non-premises,\n \ncloud,\n \nand\n \nmobile.\n \u25cf Prepackaged verified distributions which offer a one-stop solution for developers to get started quickly \nand\n \nreliably\n \nin\n \nany\n \nenvironment.\n \u25cf Multiple developer interfaces like CLI and SDKs for Python, Typescript, iOS, and Android. \u25cf Standalone applications as examples for how to build production-grade AI applications with Llama \nStack.\n \nLlama Stack Benefits \n\u25cf Flexible Options: Developers can choose their preferred infrastructure without changing APIs and enjoy \nflexible\n \ndeployment\n \nchoices.\n \u25cf Consistent Experience: With its unified APIs, Llama Stack makes it easier to build, test, and deploy AI \napplications\n \nwith\n \nconsistent\n \napplication\n \nbehavior.\n \u25cf Robust Ecosystem: Llama Stack is already integrated with distribution partners (cloud providers, \nhardware\n \nvendors,\n \nand\n \nAI-focused\n \ncompanies)\n \nthat\n \noffer\n \ntailored\n \ninfrastructure,\n \nsoftware,\n \nand\n \nservices\n \nfor\n \ndeploying\n \nLlama\n \nmodels.\n \nLlama 4 Maverick \n Llama 4 Maverick is a Mixture-of-Experts (MoE) model with 17 billion active parameters and 128 experts. \n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model experts\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9mAXEOvOfMup6u" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GaQJtU7pcY6w7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " L", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "q4lslOYYHnr5IP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "lama", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6oz6SHQVeufF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ecdCAkflBM9nZ6d" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "4", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8v85nLwLgtjkxyg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " Maver", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NMeJSqXuu2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "ick", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "p1RdfBeFxV4Uf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GOiuM2mxWT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " is", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8LEs9BVZweIow" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TTBMUF8seY54gd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " Mi", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5namyFfEh57XS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "xture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1gJgnqE1SZ5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "-of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wEImop2365qsS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "X6H9a5iFeAkAhpU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "Experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qEPnJkkw1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " (", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "p3yf4TRUYdaBSa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "Mo", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WFEKUJUOF4MKrm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "E", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "93ciJDT2caXproR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": ")", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NQ4VVCkxwtuIxJt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ke3XThIbnJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " with", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "S1vLYWIy7r3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EyDsqCjB4YD9ltR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "128", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MNC8fqnLUKVjI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "T4PnWmda" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "z6eh5lAJcswUP3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wvEZU5szEFPH1Kk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RIYiWmtEuOiH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "12HWiETWUYDEhQx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "156", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "g57T8niUOMtXP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "847", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CdEvthV28QdCM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "829", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cSGlBGBu3nkVa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "497", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vJUVZRMQsV48E" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rzxCsnLb6rX2LJn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LNU761zfPNXsFC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IKc5sES0GC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-b46a06f7d0c1", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 35, + "prompt_tokens": 988, + "total_tokens": 1023, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "VTbzbzijYTiy" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/ced781861a2e5ed75a37b9a2fc07a98f92a88d4c1ea550aa05011c5270184916.json b/tests/integration/responses/recordings/ced781861a2e5ed75a37b9a2fc07a98f92a88d4c1ea550aa05011c5270184916.json new file mode 100644 index 000000000..0a55bae94 --- /dev/null +++ b/tests/integration/responses/recordings/ced781861a2e5ed75a37b9a2fc07a98f92a88d4c1ea550aa05011c5270184916.json @@ -0,0 +1,5319 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_filter_compound_or[client_with_models-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "Show me marketing and sales documents" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_23WRIrHGU36iECmGK5iHCAAJ", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\": \"marketing documents\"}" + } + }, + { + "index": 1, + "id": "call_WvfMjaowll1M9Wj78NvoaEPu", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\": \"sales documents\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_23WRIrHGU36iECmGK5iHCAAJ", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 3 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-66545595855, score: 0.002369960119027428, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-66545595855', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-66545595855|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-66545595857, score: 0.002158784645354334, attributes: {'region': 'eu', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'eu_marketing_q1.txt', 'document_id': 'file-66545595857', 'token_count': 17.0, 'metadata_token_count': 32.0} (cite as <|file-66545595857|>)\nEuropean advertising campaign results for Q1 2023. Strong growth in EU markets.\n" + }, + { + "type": "text", + "text": "[3] document_id: file-66545595858, score: 0.0018325740484518083, attributes: {'region': 'asia', 'category': 'sales', 'date': 1688169600.0, 'filename': 'asia_sales_q3.txt', 'document_id': 'file-66545595858', 'token_count': 17.0, 'metadata_token_count': 31.0} (cite as <|file-66545595858|>)\nAsia Pacific revenue figures for Q3 2023. Record breaking quarter in Asia.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"marketing documents\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_WvfMjaowll1M9Wj78NvoaEPu", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 3 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-66545595855, score: 0.0020592709044779337, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-66545595855', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-66545595855|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-66545595858, score: 0.0017944759843167356, attributes: {'region': 'asia', 'category': 'sales', 'date': 1688169600.0, 'filename': 'asia_sales_q3.txt', 'document_id': 'file-66545595858', 'token_count': 17.0, 'metadata_token_count': 31.0} (cite as <|file-66545595858|>)\nAsia Pacific revenue figures for Q3 2023. Record breaking quarter in Asia.\n" + }, + { + "type": "text", + "text": "[3] document_id: file-66545595857, score: 0.0017688937698533602, attributes: {'region': 'eu', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'eu_marketing_q1.txt', 'document_id': 'file-66545595857', 'token_count': 17.0, 'metadata_token_count': 32.0} (cite as <|file-66545595857|>)\nEuropean advertising campaign results for Q1 2023. Strong growth in EU markets.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"sales documents\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XdGPQPiUvkZg18" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "Here", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "U9KXrqpqxByY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " are", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zzjdLInU1ji2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " some", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YUMsUNqAoph" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NKA2xD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " and", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zcuaUrNIGPxx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " sales", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rvHZ39W1jM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " documents", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "49bIx7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ":\n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MaRroEokYst" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EZYbR3MbPTylNGW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fNadGsoG2TCHMYa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qrUHyqTlin60x" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "Marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RZCTYMR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Documents", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sexSac" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ":", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rGlHaAwtZoMtgaJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "**\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PLGDUfMXXQJN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SN88vv2Eoc2dqu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " -", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pp5ksdi1vZspze" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KGnhyG6Spmx5U" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "M8fNxOP35v6R5d" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cJJK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Campaign", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "m8V9o2R" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "s", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BKMPxbHC37gY6gA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KJhwksBZ6ZzV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5tbSXG6g52reMx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Q5UfaqXnt8o57UA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CJeKVrgMDbtvnMq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ge5jm9EMDGVet" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "C4vWOdzPSQl7r2O" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ":**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HJsmbNYuayORG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " This", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5mTvbRh40A7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " document", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Mh7qVXq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " discusses", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MSuTTx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "n1hU216CYRDj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oSaj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sEZa7q" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "it9aUykIAQWaP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0Iuc2wr6o6bR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tF34hJog5HIkz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kwIs93lNP7T1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nLrm8oO1C1e6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " first", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "d6zxioYbLu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " quarter", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ejmt77V0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pUb5MOvONjEJF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "svGzq7vrZWY8xqX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qYaY20ptEv07M" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZrstyaAkaWva5mj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kcCDiDkEdyGz5iQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " noting", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "98bqc1Pdo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DZ2XHlGvMNKd60" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qGilZOLkudHeoEF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "15", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6Fbpmma7YgV4ot" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "%", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HhblN6JjioYGroz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " increase", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0Ls7w8e" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "B8snkzwgxBBwa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "O6xdOozH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KidRqNYLsnl0T" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RlNOGLUvSPgA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "f113WpE4N2R3s" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MdbBcERbV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VH2rPJfkX9C9Sv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "K0YoRj4VvNIBZbL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SeJxRpLk0XDn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HEDzG5kWNlYSZt8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "665", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2TH9KIksys2nq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "455", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QtvDnW8YhpOHC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "958", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3WKH3x18PIASG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "55", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SMgs02wVl7En1x" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CKKFKSVVyatjPiq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ">.\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "icPW125gWOzL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nVRDVIR18Mj0im" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " -", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1XRGjG4WKtAUKp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7oLVjXHoa4NiB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "European", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aiFIUayO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Advertising", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "x61Z" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Campaign", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oIKPuZL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Results", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jJrv07yR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "svE9JZ1ohEnO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "u1Qjnc5voABuDh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RHeEOOYDQBNgqUu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QOlFXrw8Oky2lvV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DZ0GhvBYiHMz5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "M4YDju4MSAk5trc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ":**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jzU93BUlsMEdD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " This", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BYXaQ4r6L7D" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " document", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VVDUbCS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " summarizes", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kaG7r" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EpQuVKWEIJXC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " results", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YQu5Fgmx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "osvH63jj14TX0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " advertising", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6JQz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hwRMG7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "749CQoHIqLvYs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Europe", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YndeezPy5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FTuQvLFg0PfY09a" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " reporting", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dj1I03" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " strong", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hac6e4uMJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " growth", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HPr0QHfE2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pPb5gSzaweV8f" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " EU", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pdVa7p1jdNHFD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " markets", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CVzAb4qi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "30vqYgCRn8Pf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HwMbpv7eiiK2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " same", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DwMSqk8FPXX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " period", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5Ysl62z27" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8iCfjXS155k6td" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ooFuPXfLHoRnXZ8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2zXyLVeFTjXC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DhHIYZWpRM4yWIl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "665", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jrIhDBQy41thm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "455", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "P5a8wui5R8TH4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "958", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IX3QKXxAZ2ec5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "57", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KhfYlHu3G0j7ON" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "uk8g4lNDirw0HAC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ">", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bPWTs0QZmXVzHxi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ".\n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4cUijEPcGP7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "2", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UTWq2WucStv8GBz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rbfRadw8IxHjdDZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1rSJBtQSpPQZx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "Sales", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "C7McWLKOkvw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Documents", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SOSLyt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ":", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "piUsWn8EBb7NjCa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "**\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Kb8UQh5ooOOn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "owsU7AvtxRl3kl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " -", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ExGbBEj0ZZiEeO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LkhE90XcCt6QB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "Asia", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ro9yRuQMye1f" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Pacific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QJPNzWYh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CVZnpy4Y" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Figures", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4LCiSbby" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NZBAX47EqHal" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "k4wYrq2UJsc8FI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XnvMVcQXnZVg53T" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "G86LWlfiKXx9Ezf" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kGj2b6q4bKQjS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SOHSHJ5tpvjc3EN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ":**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JIxK4WXw9hNN7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " This", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2V0SGyXuBBb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " document", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LtTGZ5l" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " outlines", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Oef5Th7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xuVMjXg6INli" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gXoUX25I" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " figures", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MhYIddql" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CojnKuUoJdEh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fndEVKE6cEET" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Asia", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sTVeoEwpIaI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Pacific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QLkH7h9f" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AG87hmAQm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "49wW6MlCMn4mv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SWGxSzMrfUoK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " third", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tfqImYMumN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " quarter", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gcpKnfPS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "40j8DJWHcu06X" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VQIhIYUHOTkVVaq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "w2OFvAuBs6SkU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yFJPhxFj2p8NG43" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "j7jM9iqpVCCQUwJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " marking", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "uxjZvTlO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "07u6pYFZV57uUl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " record", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VSMUQ0Sry" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "-breaking", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4LTMtCq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " quarter", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jFHWxBdu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xvUWnFlQr9dYw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " Asia", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "a3BGrtj1ZNq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dPT7A9SLFuH4sc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TwAufdUHaGxnpXx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yY9mj10ACA9Z" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "HKlp5d8z1sCRnvo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "665", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xdwJpwbzCAAeZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "455", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "28DGC41ugGYBT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "958", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TQukAPywNWLCT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "58", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "S3fJdG0iCX5tYc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1sVu1FvGcBfoRQ8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ">", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NejYFG2Dhq9dell" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": ".\n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DdjiLHp9ldg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "Feel", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6DNGC3GK7maK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " free", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lPDuTrpbpsY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " to", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jr8PFNUPcfeuU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " ask", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "b6kvXXT5e0cM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " if", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rxtEujuhrSKRE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XTLKkpLrB30T" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " need", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "c2s2qJpL62p" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " more", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sW13r2ijB7n" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " detailed", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nGIlF9a" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " information", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ibll" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " about", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qIy4kyp8Rg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " any", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oFiPqolmcN20" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " specific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7XspzkQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": " document", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9zcTaMM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": "!", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FvykFc3GIhoBbVo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "icraAZ8N3I" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-ced781861a2e", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 190, + "prompt_tokens": 1132, + "total_tokens": 1322, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "hN0VoxNXyt" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/e30fbbfccc7f5b97dc6624fdfaeb656c32bdeef203f7d956848838090a8d97a0.json b/tests/integration/responses/recordings/e30fbbfccc7f5b97dc6624fdfaeb656c32bdeef203f7d956848838090a8d97a0.json new file mode 100644 index 000000000..b177c4a54 --- /dev/null +++ b/tests/integration/responses/recordings/e30fbbfccc7f5b97dc6624fdfaeb656c32bdeef203f7d956848838090a8d97a0.json @@ -0,0 +1,660 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search_empty_vector_store[client_with_models-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "id": "call_mj487Ks2sh1tl4Ic45p6c05I", + "function": { + "arguments": "", + "name": "knowledge_search" + }, + "type": "function" + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wqUy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "{\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "30F" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "query", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "T" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\":\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "o" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "L", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mD2xK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "lama", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " ", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gekaZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "4", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "I28xt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " Maver", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "ick", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kvU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " model", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " number", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wb14MkADYXLgXVa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " of", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tz6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " experts", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zjEyGJrVXsF0qr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\"}", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mmH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "tool_calls", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YLwR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e30fbbfccc7f", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 24, + "prompt_tokens": 74, + "total_tokens": 98, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "lrOfy3Ovh9Ay9TZ" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/e858ad8875d3c11059189000e91b485ae0e322a9a0cdf8f9502002b09b72b2e6.json b/tests/integration/responses/recordings/e858ad8875d3c11059189000e91b485ae0e322a9a0cdf8f9502002b09b72b2e6.json new file mode 100644 index 000000000..c1a0ac32d --- /dev/null +++ b/tests/integration/responses/recordings/e858ad8875d3c11059189000e91b485ae0e322a9a0cdf8f9502002b09b72b2e6.json @@ -0,0 +1,2360 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_filter_by_region[client_with_models-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "What are the updates from the US region?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_e9va2TPHaw7wGHW4FVbhLLGF", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"latest news updates from the US\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_e9va2TPHaw7wGHW4FVbhLLGF", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 2 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-446066738450, score: 0.004746808510792406, attributes: {'region': 'us', 'category': 'engineering', 'date': 1680307200.0, 'filename': 'us_engineering_q2.txt', 'document_id': 'file-446066738450', 'token_count': 18.0, 'metadata_token_count': 32.0} (cite as <|file-446066738450|>)\nUS technical updates for Q2 2023. New features deployed in the US region.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-446066738449, score: 0.0030296457418813576, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-446066738449', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-446066738449|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"latest news updates from the US\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aqhlT3eLRWQVwn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "I", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "j7LxLf9nkbMUsat" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " wasn't", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Yb3E2vjQp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " able", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BR6Ep6mHUWl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " to", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jzvUpyQg6t4KY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " find", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JME4a5nGFyY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "42PfnWBpmMEZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " most", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5sjtigBbKs8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " recent", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TKPDi6h5C" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " news", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xfcBAdtmVYd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " updates", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vyOA40EL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " from", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "WKvCRFY5i52" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "voRN63Cxay3h" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "m5waqSvq8nrmC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bAIBogqDBYLQNJz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " However", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sImHMBhP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PAXzYayA6u8QaaF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " I", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rpK1HnedyTx1Bm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " found", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TSzSuVXOB2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " some", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oiHPqyf8rj1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " information", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zyzU" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " from", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LRkXcesu3kv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5CBXfrNr5m88x0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "2", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9PnCqc0rnxrXYq2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XFJq7Nmwtc9HsCL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "etKgbMagTzQEo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wruhogHDwJaUzJc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " about", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0RHggce0tm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " new", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UMdtawsVbdqd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " technical", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TXEIpE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " features", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "u1W8Yci" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " deployed", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GR4xsQ9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QU7mH4VrUAVOd" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qjeREFEKK6nW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qMoAzMOaFxAqF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QhKyLz28W" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "V1fpkM29YgqJG6" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CWHl6w2xP93DUeE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "O3C1cO8u6FBB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ptqckvWLesqbhgF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "446", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "p6811HKToTLjy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "066", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0Sa6Uo6Y5pn92" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "738", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7uw3kvgy6SwHO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "450", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ib0kPdAMq2DjA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lnD9KahYPqKmzmO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": ">", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3GppRQgYKPKeHAe" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " and", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9LnH5w7ldqMY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1GX8zk8CEPBra1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " note", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LPbytQBnCrp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " on", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ujy94Y5IDckl5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "soNT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "L2dXaP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "00yEtV5StjzAZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GN2wLSQU268YJi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OHt1oCwSLstZNsF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kgMyyevpdoWkOZP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZUPGxzCq0Smmb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BKtG6sQzGFt9Jlz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YdhDAdYKfXOYBik" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " which", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "69J0RaD351" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " led", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "P38reGXyb7Mm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " to", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VhkGg6hSFv2Yc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8oo41u3oe7dqRF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vVOeAUoIlL2Dr45" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "15", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5O1Y1KhyPD9FiH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "%", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wIRIrsBe79ovgA7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4f3i8JTv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " increase", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "k7xvmJi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wCzB9BAnRxCNt" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "G1QnFuuZ1Zxh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RH76JhPNigfCV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9n7UQGypA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "7A2ePQsmZL6Unj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0sqmXYlUgeA5ad0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hNr6Yln8H2Da" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OC8EK7rWWZ3QeZk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "446", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZYFHFT47qvkRR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "066", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rn6vSev3yHACP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "738", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "v6G9elSOI51Vq" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "449", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2uVAEusItKumD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "5FK7OttxZAl0pGP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rz0blhyxkJsBC2" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eOmKAZr9Iz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-e858ad8875d3", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 82, + "prompt_tokens": 468, + "total_tokens": 550, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "zhqZ1oh8DC60I" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/f27d01b45fdcb22d0f17dfc1443b33687ed1de90043fb14ef5b0627301dc3afa.json b/tests/integration/responses/recordings/f27d01b45fdcb22d0f17dfc1443b33687ed1de90043fb14ef5b0627301dc3afa.json new file mode 100644 index 000000000..80d540be6 --- /dev/null +++ b/tests/integration/responses/recordings/f27d01b45fdcb22d0f17dfc1443b33687ed1de90043fb14ef5b0627301dc3afa.json @@ -0,0 +1,1191 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search_empty_vector_store[client_with_models-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_mj487Ks2sh1tl4Ic45p6c05I", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model number of experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_mj487Ks2sh1tl4Ic45p6c05I", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 0 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model number of experts\". Use them as supporting information only in answering this query.\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SRIlpdajZx8FO4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": "I", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0bprKCxqVUT1IzO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " couldn't", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gufTJos" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " find", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0AvzawzpiKm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " specific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "bUJDVvX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " information", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GrXx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " on", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NMOFb2ld93Xol" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "w15SXaCjAMFj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " number", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "27B3YvlcC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2HxNBEwC17WR3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GW7ttzUM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "D6d19PSXPXrBn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "mFt8405teF5j" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " L", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LwYKpJV7S9PiWW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": "lama", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SYXxmYtps79F" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lpI5leMBjGqY9pQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": "4", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VbSAwY12HmP5brn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " Maver", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FYSKXqx8uk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": "ick", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "v9DS20Kn7CGoi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ja8yRMZINL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "40vCQeypW8n1Qlc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " You", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Zk30ZUxBclCm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " might", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "R4iAb4Bfph" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " need", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Gafvg4ZIPf7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " to", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jMexvTa4ndGz1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " refer", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LRMPjt7rIY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " to", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TrWcCKSieTc6E" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UlGsWusYETYB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " official", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "h00N110" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " documentation", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " or", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UinXMBmHRF56N" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " announcements", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4j" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " from", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "r82bBftENEV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1CXANU3X2bkO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " developers", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "N2K2y" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "C0Ed59GaOm2l" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " precise", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "T70MK9LI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": " details", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ar6pbTXi" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Qdz1YJaJbTR9nsh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MJhFNn9Hl7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f27d01b45fdc", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 39, + "prompt_tokens": 163, + "total_tokens": 202, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "U92EityXUiyFJ" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/f5ba8a29a9c1a20e23214598f57bf223828256fb59234fbd33d7c19e482ef854.json b/tests/integration/responses/recordings/f5ba8a29a9c1a20e23214598f57bf223828256fb59234fbd33d7c19e482ef854.json new file mode 100644 index 000000000..d9d0e9fe2 --- /dev/null +++ b/tests/integration/responses/recordings/f5ba8a29a9c1a20e23214598f57bf223828256fb59234fbd33d7c19e482ef854.json @@ -0,0 +1,2684 @@ +{ + "test_id": "tests/integration/responses/test_file_search.py::test_response_file_search_filter_by_category[client_with_models-txt=openai/gpt-4o]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "Show me all marketing reports" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_ymvqIkud4SsWScbsp71WX2Dv", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"all marketing reports\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_ymvqIkud4SsWScbsp71WX2Dv", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 2 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-630021438843, score: 0.002382802518405855, attributes: {'region': 'us', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'us_marketing_q1.txt', 'document_id': 'file-630021438843', 'token_count': 21.0, 'metadata_token_count': 32.0} (cite as <|file-630021438843|>)\nUS promotional campaigns for Q1 2023. Revenue increased by 15% in the US region.\n" + }, + { + "type": "text", + "text": "[2] document_id: file-630021438845, score: 0.002299599142141726, attributes: {'region': 'eu', 'category': 'marketing', 'date': 1672531200.0, 'filename': 'eu_marketing_q1.txt', 'document_id': 'file-630021438845', 'token_count': 17.0, 'metadata_token_count': 32.0} (cite as <|file-630021438845|>)\nEuropean advertising campaign results for Q1 2023. Strong growth in EU markets.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"all marketing reports\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4N3tp1S9tG28pA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "Here", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3200bmW3d5LS" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " are", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "icOnsMG8XjZY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BbiVCyfXUk68" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NCG4Zu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " reports", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fsNjMgKm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": ":\n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TQwaCzP6NLm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BvL4pkg1rAUsy2M" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IGtBzb0Od4HghWa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9liSZV5esGAaE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2wVlojWNs6TpdF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " Marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3wrOaa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " Report", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fDxFfB5eX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gbK3KPw9fAFs" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "J2j0xqJtGPap7w" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zb3euNdyWlcjpXc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wWRXXTzFMTYXeP0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ilaeyx1BqbgZD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DxUsz43eJDNNhbj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Z0Y9820piNv40Y" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": ":", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AE38Rd0KyZnMREA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " The", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cqYUOSzTWeob" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " report", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FPNh7M5iJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " highlights", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Qz0rY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " promotional", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "oy56" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " campaigns", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4ZUWpm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zvoUYGJN9SxEg" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PLAVerfDu4qV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " United", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "r9MEWdRX1" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " States", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9RZKWzftx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9PrQiraxny6ioez" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " noting", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "iP5zVVAvh" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " a", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DK61Nsnswx7ZAK" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LKey5lze3PBdBw8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "15", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "SFY6qLBHbhBoz5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "%", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wnZ9137DkdRtHnO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " increase", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2UxD8eW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "izLdQZY7PY913" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " revenue", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "95pa26qo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "li9rjxSnrTNXp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "t1StV9n5uZFD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " US", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "p9MdlLIU3HaH0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " region", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CIM9ziWZa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cgWeWoQHbU2fTu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aVK9Tjns7uHQh16" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fsVP8sKv0tR8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "L1jwZfUaSQpM4qM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "630", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Fy7YZIPEcZKm5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "021", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pdCoRFv2k8zpQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "438", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Y0hsHzSES4VUo" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "843", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "D5vFkTtBMBfHP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PRIQRkAhi0ZbGFT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": ">", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BVIRRvUC0DJf8w4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": ".\n\n", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YSlEJCMJNV9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "2", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "odTW1kHMpKzOCzR" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": ".", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Fa8dy1nw3lQ2VGx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " **", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IN5shTxuimZj0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "European", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "0j0VwXeA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " Marketing", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "weUOZe" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " Report", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BHWp7GwgD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " for", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CXAY9zsXV9fV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " Q", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nT76pMsMcg2e6r" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "1", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3fwuaSCwvpZwcnL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "fxjItuhdH7LNciW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "202", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PiRaydhUnVTlm" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "3", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "P8sjxeap5reKf1d" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "**", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pnQWynGG5fjcs5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": ":", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "I0udDGwQurbphXj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " This", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qcE4ND7CQKV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " report", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "RhvpSlXJb" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " focuses", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "porIjgLV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " on", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "R8B0GNlG7RMnD" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " advertising", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qGCn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " campaign", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4mzlLa9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " results", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ffQEjjrk" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UAHd3HQLxRjvz" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " Europe", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FjrIOJBji" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "B7fyyvXVxvNY2so" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " indicating", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "X4ES5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " strong", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jHeWXatus" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " growth", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dwGuvRNb4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "kBNLi3RoTmt7W" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " EU", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gH61e6JTi9jfM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " markets", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OR0WZkgp" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JcDso3jKuaMHzB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lyhNXzIAlnTHB82" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IrFupLnQwQf8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "apaTzs0DuUoMiUL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "630", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "y0HYANL4WSuYW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "021", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "MVJhM1B1VFq25" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "438", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8xPNVYlBjkKZC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "845", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2XVvctfn3uPYV" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "we6kObliWDle0WB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "2KOaYFLi1Q3RkY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "zBjTjqxhW0" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f5ba8a29a9c1", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 94, + "prompt_tokens": 456, + "total_tokens": 550, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "mqEOVo9hWj09s" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/f80d49a32ea559ef5f0020301475b04deeb96c97931d3413adf0a4e5216a42d4.json b/tests/integration/responses/recordings/f80d49a32ea559ef5f0020301475b04deeb96c97931d3413adf0a4e5216a42d4.json new file mode 100644 index 000000000..53dd33aca --- /dev/null +++ b/tests/integration/responses/recordings/f80d49a32ea559ef5f0020301475b04deeb96c97931d3413adf0a4e5216a42d4.json @@ -0,0 +1,660 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_non_streaming_file_search_empty_vector_store[openai_client-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": [ + { + "index": 0, + "id": "call_ltsd3q9G7fq4by5VmgdvtNRX", + "function": { + "arguments": "", + "name": "knowledge_search" + }, + "type": "function" + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sdM3" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "{\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "m73" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "query", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "d" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\":\"", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "J" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "L", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VHl6C" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "lama", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "cL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " ", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "nSM0I" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "4", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rq64c" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " Maver", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "ick", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "q5M" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " model", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " number", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "tzlHgv0gPZ2Y7be" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " of", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "8LG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": " experts", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "UbWx20CRkD2j80" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": [ + { + "index": 0, + "id": null, + "function": { + "arguments": "\"}", + "name": null + }, + "type": null + } + ] + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "CRw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "tool_calls", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "jPOO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f80d49a32ea5", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 24, + "prompt_tokens": 74, + "total_tokens": 98, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "I4x1yzasaOQSFKk" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/responses/recordings/f970cb793e3a68879444e3b218cfbe37829f7ed7ca4706ff0cbb6113f9a3253b.json b/tests/integration/responses/recordings/f970cb793e3a68879444e3b218cfbe37829f7ed7ca4706ff0cbb6113f9a3253b.json new file mode 100644 index 000000000..b3881f6ff --- /dev/null +++ b/tests/integration/responses/recordings/f970cb793e3a68879444e3b218cfbe37829f7ed7ca4706ff0cbb6113f9a3253b.json @@ -0,0 +1,2239 @@ +{ + "test_id": "tests/integration/responses/test_tool_responses.py::test_response_sequential_file_search[client_with_models-txt=openai/gpt-4o:emb=sentence-transformers/nomic-ai/nomic-embed-text-v1.5:dim=768]", + "request": { + "method": "POST", + "url": "https://api.openai.com/v1/v1/chat/completions", + "headers": {}, + "body": { + "model": "gpt-4o", + "messages": [ + { + "role": "user", + "content": "How many experts does the Llama 4 Maverick model have?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_FzhOmTdZThRndI5rSASPdAqr", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model number of experts\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_FzhOmTdZThRndI5rSASPdAqr", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-797509666839, score: 0.01927231682811354, attributes: {'filename': 'test_sequential_file_search.txt', 'document_id': 'file-797509666839', 'token_count': 19.0, 'metadata_token_count': 11.0} (cite as <|file-797509666839|>)\nThe Llama 4 Maverick model has 128 experts in its mixture of experts architecture.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model number of experts\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + }, + { + "role": "assistant", + "content": "The Llama 4 Maverick model has 128 experts in its mixture of experts architecture <|file-797509666839|>." + }, + { + "role": "user", + "content": "Can you tell me more about the architecture?" + }, + { + "role": "assistant", + "content": "", + "tool_calls": [ + { + "index": 0, + "id": "call_0ABjXmEaManGBvCYVZD4QgMt", + "type": "function", + "function": { + "name": "knowledge_search", + "arguments": "{\"query\":\"Llama 4 Maverick model architecture details\"}" + } + } + ] + }, + { + "role": "tool", + "tool_call_id": "call_0ABjXmEaManGBvCYVZD4QgMt", + "content": [ + { + "type": "text", + "text": "knowledge_search tool found 1 chunks:\nBEGIN of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "[1] document_id: file-797509666839, score: 0.005821830799489026, attributes: {'filename': 'test_sequential_file_search.txt', 'document_id': 'file-797509666839', 'token_count': 19.0, 'metadata_token_count': 11.0} (cite as <|file-797509666839|>)\nThe Llama 4 Maverick model has 128 experts in its mixture of experts architecture.\n" + }, + { + "type": "text", + "text": "END of knowledge_search tool results.\n" + }, + { + "type": "text", + "text": "The above results were retrieved to help answer the user's query: \"Llama 4 Maverick model architecture details\". Use them as supporting information only in answering this query. Cite sources immediately at the end of sentences before punctuation, using `<|file-id|>` format (e.g., 'This is a fact <|file-Cn3MSNn72ENTiiq11Qda4A|>.'). Do not add extra punctuation. Use only the file IDs provided (do not invent new ones).\n" + } + ] + } + ], + "stream": true, + "stream_options": { + "include_usage": true + }, + "tools": [ + { + "type": "function", + "function": { + "name": "knowledge_search", + "description": "Search for information in a database.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "The query to search for. Can be a natural language sentence or keywords." + } + }, + "required": [ + "query" + ] + } + } + } + ] + }, + "endpoint": "/v1/chat/completions", + "model": "gpt-4o" + }, + "response": { + "body": [ + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "", + "function_call": null, + "refusal": null, + "role": "assistant", + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rsd7d3rp5kbEVl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "The", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ODJOwvLFURckN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " search", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xZb015AGx" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " did", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3JGWBbu6DPDN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " not", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wckpIDwdjVDO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " return", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ldxxVIrQG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " detailed", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "QKiep2I" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " information", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PN7l" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " on", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Ur07TqLu832VA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "sPmbNMurjXRy" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " L", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "aPlzubhDMGESKu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "lama", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "GKINsm8cApiJ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1oce53N1sG0TvTv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "4", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "apwsDYdU0Sa7ecI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " Maver", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lTQzNiGeSA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "ick", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "9k98JY73pqRJ7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ugrRMI4fEF" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "'s", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6QvjTKjAVkdg5a" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " architecture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Vzc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " beyond", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vNcwB3Qed" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "VPWpdr5Fl3Ip" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " fact", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xazWtEOj5Kj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " that", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XADhfcr8VVN" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " it", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "vCKOntIT1zH0d" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " includes", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6Dtr2fH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " ", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "TLAxs44DOUGC7Os" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "128", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FWII1RcbMI53t" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NFr4G1k5" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Pk903dzZmEQ8E" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " its", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "eoSzZZOvuh6g" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " mixture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "4alUaiBM" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "OX8jc0x591gH7" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " experts", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "BSBTyRnI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " design", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "6hDOBVMq4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " <", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "LnwqjhP9VT9Ooc" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Sio7mRGTVjjrluP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "file", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "F1432MVyFi6k" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "-", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "uZnDp5RxdElbmFG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "797", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DkioNrKVpHgm4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "509", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "pNTgUVRUx1zmI" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "666", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "IuAWvaapdXENa" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "839", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "lPzK8ydEBn7KZ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "|", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "i7j8Lcp3w6fiwfB" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": ">.", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XOa8gEi2dmWmwv" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " If", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "H3SJqnjZ7Pqla" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "JcW6AJ5otYLu" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " have", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "3zHp4CcYvt4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " specific", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gbNW68h" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " aspects", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "d3l4elcj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " of", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "wm2dCDI1w9YZT" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xksFX6yWVCKr" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " architecture", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "EBl" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " you", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "uHyFNawwHG4S" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " are", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "XWndZ3Vs6Fl4" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " interested", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "KryRC" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " in", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "PsbGeC1p8q1qW" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "R0ewazqkDYFcutH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " such", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DunAPSZH5pH" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " as", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "rPK25ptTTBfmO" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " the", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1rpL0ku9AVho" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " model", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "Q4tHIRqic8" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "'s", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xnAtIpnDFBpzrn" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " layers", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "dobI7KtDw" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "qRPkAtKOKDpghrA" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " computational", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ZQ" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " pathway", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "AVY3TggP" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "V4ADAwStu1UFXpj" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " or", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "xtIJsJ9g6yDTG" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " unique", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "FqoXIcjuE" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " features", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "NBtG144" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": ",", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "ktFPoLRC0Zopjl9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " please", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "1FQhYXLuY" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " let", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "DdsYWqEjWxdX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " me", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "gEWWKiK0fl8iX" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": " know", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "hpfipWYz4jL" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": "!", + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": null, + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "YavpvIVxZjJr6x9" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [ + { + "delta": { + "content": null, + "function_call": null, + "refusal": null, + "role": null, + "tool_calls": null + }, + "finish_reason": "stop", + "index": 0, + "logprobs": null + } + ], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": null, + "obfuscation": "yfTg1otZak" + } + }, + { + "__type__": "openai.types.chat.chat_completion_chunk.ChatCompletionChunk", + "__data__": { + "id": "rec-f970cb793e3a", + "choices": [], + "created": 0, + "model": "gpt-4o-2024-08-06", + "object": "chat.completion.chunk", + "service_tier": "default", + "system_fingerprint": "fp_f64f290af2", + "usage": { + "completion_tokens": 76, + "prompt_tokens": 633, + "total_tokens": 709, + "completion_tokens_details": { + "accepted_prediction_tokens": 0, + "audio_tokens": 0, + "reasoning_tokens": 0, + "rejected_prediction_tokens": 0 + }, + "prompt_tokens_details": { + "audio_tokens": 0, + "cached_tokens": 0 + } + }, + "obfuscation": "CCFg1IMN4ffFL" + } + } + ], + "is_streaming": true + }, + "id_normalization_mapping": {} +} diff --git a/tests/integration/test_persistence_integration.py b/tests/integration/test_persistence_integration.py new file mode 100644 index 000000000..e9b80dc0c --- /dev/null +++ b/tests/integration/test_persistence_integration.py @@ -0,0 +1,71 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +import yaml + +from llama_stack.core.datatypes import StackRunConfig +from llama_stack.core.storage.datatypes import ( + PostgresKVStoreConfig, + PostgresSqlStoreConfig, + SqliteKVStoreConfig, + SqliteSqlStoreConfig, +) + + +def test_starter_distribution_config_loads_and_resolves(): + """Integration: Actual starter config should parse and have correct storage structure.""" + with open("llama_stack/distributions/starter/run.yaml") as f: + config_dict = yaml.safe_load(f) + + config = StackRunConfig(**config_dict) + + # Config should have named backends and explicit store references + assert config.storage is not None + assert "kv_default" in config.storage.backends + assert "sql_default" in config.storage.backends + assert isinstance(config.storage.backends["kv_default"], SqliteKVStoreConfig) + assert isinstance(config.storage.backends["sql_default"], SqliteSqlStoreConfig) + + stores = config.storage.stores + assert stores.metadata is not None + assert stores.metadata.backend == "kv_default" + assert stores.metadata.namespace == "registry" + + assert stores.inference is not None + assert stores.inference.backend == "sql_default" + assert stores.inference.table_name == "inference_store" + assert stores.inference.max_write_queue_size > 0 + assert stores.inference.num_writers > 0 + + assert stores.conversations is not None + assert stores.conversations.backend == "sql_default" + assert stores.conversations.table_name == "openai_conversations" + + +def test_postgres_demo_distribution_config_loads(): + """Integration: Postgres demo should use Postgres backend for all stores.""" + with open("llama_stack/distributions/postgres-demo/run.yaml") as f: + config_dict = yaml.safe_load(f) + + config = StackRunConfig(**config_dict) + + # Should have postgres backend + assert config.storage is not None + assert "kv_default" in config.storage.backends + assert "sql_default" in config.storage.backends + postgres_backend = config.storage.backends["sql_default"] + assert isinstance(postgres_backend, PostgresSqlStoreConfig) + assert postgres_backend.host == "${env.POSTGRES_HOST:=localhost}" + + kv_backend = config.storage.backends["kv_default"] + assert isinstance(kv_backend, PostgresKVStoreConfig) + + stores = config.storage.stores + # Stores target the Postgres backends explicitly + assert stores.metadata is not None + assert stores.metadata.backend == "kv_default" + assert stores.inference is not None + assert stores.inference.backend == "sql_default" diff --git a/tests/integration/vector_io/test_openai_vector_stores.py b/tests/integration/vector_io/test_openai_vector_stores.py index e21b233bc..626faf42d 100644 --- a/tests/integration/vector_io/test_openai_vector_stores.py +++ b/tests/integration/vector_io/test_openai_vector_stores.py @@ -8,14 +8,15 @@ import time from io import BytesIO import pytest -from llama_stack_client import BadRequestError, NotFoundError +from llama_stack_client import BadRequestError from openai import BadRequestError as OpenAIBadRequestError -from openai import NotFoundError as OpenAINotFoundError from llama_stack.apis.vector_io import Chunk from llama_stack.core.library_client import LlamaStackAsLibraryClient from llama_stack.log import get_logger +from ..conftest import vector_provider_wrapper + logger = get_logger(name=__name__, category="vector_io") @@ -133,8 +134,9 @@ def compat_client_with_empty_stores(compat_client): clear_files() +@vector_provider_wrapper def test_openai_create_vector_store( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test creating a vector store using OpenAI API.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -146,6 +148,7 @@ def test_openai_create_vector_store( metadata={"purpose": "testing", "environment": "integration"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -159,14 +162,18 @@ def test_openai_create_vector_store( assert hasattr(vector_store, "created_at") -def test_openai_create_vector_store_default(compat_client_with_empty_stores, client_with_models): +@vector_provider_wrapper +def test_openai_create_vector_store_default(compat_client_with_empty_stores, client_with_models, vector_io_provider_id): skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) - vector_store = compat_client_with_empty_stores.vector_stores.create() + vector_store = compat_client_with_empty_stores.vector_stores.create( + extra_body={"provider_id": vector_io_provider_id} + ) assert vector_store.id +@vector_provider_wrapper def test_openai_list_vector_stores( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test listing vector stores using OpenAI API.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -179,6 +186,7 @@ def test_openai_list_vector_stores( metadata={"type": "test"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) store2 = client.vector_stores.create( @@ -186,6 +194,7 @@ def test_openai_list_vector_stores( metadata={"type": "test"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -206,8 +215,9 @@ def test_openai_list_vector_stores( assert len(limited_response.data) == 1 +@vector_provider_wrapper def test_openai_retrieve_vector_store( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test retrieving a specific vector store using OpenAI API.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -220,6 +230,7 @@ def test_openai_retrieve_vector_store( metadata={"purpose": "retrieval_test"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -233,8 +244,9 @@ def test_openai_retrieve_vector_store( assert retrieved_store.object == "vector_store" +@vector_provider_wrapper def test_openai_update_vector_store( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test modifying a vector store using OpenAI API.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -247,6 +259,7 @@ def test_openai_update_vector_store( metadata={"version": "1.0"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) time.sleep(1) @@ -264,8 +277,9 @@ def test_openai_update_vector_store( assert modified_store.last_active_at > created_store.last_active_at +@vector_provider_wrapper def test_openai_delete_vector_store( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test deleting a vector store using OpenAI API.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -278,6 +292,7 @@ def test_openai_delete_vector_store( metadata={"purpose": "deletion_test"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -294,8 +309,9 @@ def test_openai_delete_vector_store( client.vector_stores.retrieve(vector_store_id=created_store.id) +@vector_provider_wrapper def test_openai_vector_store_search_empty( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test searching an empty vector store using OpenAI API.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -308,6 +324,7 @@ def test_openai_vector_store_search_empty( metadata={"purpose": "search_testing"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -323,8 +340,14 @@ def test_openai_vector_store_search_empty( assert search_response.has_more is False +@vector_provider_wrapper def test_openai_vector_store_with_chunks( - compat_client_with_empty_stores, client_with_models, sample_chunks, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, + client_with_models, + sample_chunks, + embedding_model_id, + embedding_dimension, + vector_io_provider_id, ): """Test vector store functionality with actual chunks using both OpenAI and native APIs.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -338,6 +361,7 @@ def test_openai_vector_store_with_chunks( metadata={"purpose": "chunks_testing"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -380,6 +404,7 @@ def test_openai_vector_store_with_chunks( ("What inspires neural networks?", "doc4", "ai"), ], ) +@vector_provider_wrapper def test_openai_vector_store_search_relevance( compat_client_with_empty_stores, client_with_models, @@ -387,6 +412,7 @@ def test_openai_vector_store_search_relevance( test_case, embedding_model_id, embedding_dimension, + vector_io_provider_id, ): """Test that OpenAI vector store search returns relevant results for different queries.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -402,6 +428,7 @@ def test_openai_vector_store_search_relevance( metadata={"purpose": "relevance_testing"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -430,8 +457,14 @@ def test_openai_vector_store_search_relevance( assert top_result.score > 0 +@vector_provider_wrapper def test_openai_vector_store_search_with_ranking_options( - compat_client_with_empty_stores, client_with_models, sample_chunks, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, + client_with_models, + sample_chunks, + embedding_model_id, + embedding_dimension, + vector_io_provider_id, ): """Test OpenAI vector store search with ranking options.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -445,6 +478,7 @@ def test_openai_vector_store_search_with_ranking_options( metadata={"purpose": "ranking_testing"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -483,8 +517,14 @@ def test_openai_vector_store_search_with_ranking_options( assert result.score >= threshold +@vector_provider_wrapper def test_openai_vector_store_search_with_high_score_filter( - compat_client_with_empty_stores, client_with_models, sample_chunks, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, + client_with_models, + sample_chunks, + embedding_model_id, + embedding_dimension, + vector_io_provider_id, ): """Test that searching with text very similar to a document and high score threshold returns only that document.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -498,6 +538,7 @@ def test_openai_vector_store_search_with_high_score_filter( metadata={"purpose": "high_score_filtering"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -542,8 +583,14 @@ def test_openai_vector_store_search_with_high_score_filter( assert "python" in top_content.lower() or "programming" in top_content.lower() +@vector_provider_wrapper def test_openai_vector_store_search_with_max_num_results( - compat_client_with_empty_stores, client_with_models, sample_chunks, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, + client_with_models, + sample_chunks, + embedding_model_id, + embedding_dimension, + vector_io_provider_id, ): """Test OpenAI vector store search with max_num_results.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -557,6 +604,7 @@ def test_openai_vector_store_search_with_max_num_results( metadata={"purpose": "max_num_results_testing"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -577,8 +625,9 @@ def test_openai_vector_store_search_with_max_num_results( assert len(search_response.data) == 2 +@vector_provider_wrapper def test_openai_vector_store_attach_file( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test OpenAI vector store attach file.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -591,6 +640,7 @@ def test_openai_vector_store_attach_file( name="test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -637,8 +687,9 @@ def test_openai_vector_store_attach_file( assert "foobazbar" in top_content.lower() +@vector_provider_wrapper def test_openai_vector_store_attach_files_on_creation( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test OpenAI vector store attach files on creation.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -668,6 +719,7 @@ def test_openai_vector_store_attach_files_on_creation( file_ids=file_ids, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -700,8 +752,9 @@ def test_openai_vector_store_attach_files_on_creation( assert updated_vector_store.file_counts.failed == 0 +@vector_provider_wrapper def test_openai_vector_store_list_files( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test OpenAI vector store list files.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -714,6 +767,7 @@ def test_openai_vector_store_list_files( name="test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -773,8 +827,9 @@ def test_openai_vector_store_list_files( assert updated_vector_store.file_counts.in_progress == 0 +@vector_provider_wrapper def test_openai_vector_store_list_files_invalid_vector_store( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test OpenAI vector store list files with invalid vector store ID.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -783,14 +838,15 @@ def test_openai_vector_store_list_files_invalid_vector_store( if isinstance(compat_client, LlamaStackAsLibraryClient): errors = ValueError else: - errors = (NotFoundError, OpenAINotFoundError) + errors = (BadRequestError, OpenAIBadRequestError) with pytest.raises(errors): compat_client.vector_stores.files.list(vector_store_id="abc123") +@vector_provider_wrapper def test_openai_vector_store_retrieve_file_contents( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test OpenAI vector store retrieve file contents.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -803,6 +859,7 @@ def test_openai_vector_store_retrieve_file_contents( name="test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -848,8 +905,9 @@ def test_openai_vector_store_retrieve_file_contents( assert file_contents.attributes == attributes +@vector_provider_wrapper def test_openai_vector_store_delete_file( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test OpenAI vector store delete file.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -862,6 +920,7 @@ def test_openai_vector_store_delete_file( name="test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -912,8 +971,9 @@ def test_openai_vector_store_delete_file( assert updated_vector_store.file_counts.in_progress == 0 +@vector_provider_wrapper def test_openai_vector_store_delete_file_removes_from_vector_store( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test OpenAI vector store delete file removes from vector store.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -926,6 +986,7 @@ def test_openai_vector_store_delete_file_removes_from_vector_store( name="test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -962,8 +1023,9 @@ def test_openai_vector_store_delete_file_removes_from_vector_store( assert not search_response.data +@vector_provider_wrapper def test_openai_vector_store_update_file( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test OpenAI vector store update file.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -976,6 +1038,7 @@ def test_openai_vector_store_update_file( name="test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -1017,8 +1080,9 @@ def test_openai_vector_store_update_file( assert retrieved_file.attributes["foo"] == "baz" +@vector_provider_wrapper def test_create_vector_store_files_duplicate_vector_store_name( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """ This test confirms that client.vector_stores.create() creates a unique ID @@ -1044,6 +1108,7 @@ def test_create_vector_store_files_duplicate_vector_store_name( name="test_store_with_files", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) assert vector_store.file_counts.completed == 0 @@ -1056,6 +1121,7 @@ def test_create_vector_store_files_duplicate_vector_store_name( name="test_store_with_files", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -1086,8 +1152,15 @@ def test_create_vector_store_files_duplicate_vector_store_name( @pytest.mark.parametrize("search_mode", ["vector", "keyword", "hybrid"]) +@vector_provider_wrapper def test_openai_vector_store_search_modes( - llama_stack_client, client_with_models, sample_chunks, search_mode, embedding_model_id, embedding_dimension + llama_stack_client, + client_with_models, + sample_chunks, + search_mode, + embedding_model_id, + embedding_dimension, + vector_io_provider_id, ): skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) skip_if_provider_doesnt_support_openai_vector_stores_search(client_with_models, search_mode) @@ -1097,6 +1170,7 @@ def test_openai_vector_store_search_modes( metadata={"purpose": "search_mode_testing"}, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -1115,8 +1189,9 @@ def test_openai_vector_store_search_modes( assert search_response is not None +@vector_provider_wrapper def test_openai_vector_store_file_batch_create_and_retrieve( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test creating and retrieving a vector store file batch.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -1128,6 +1203,7 @@ def test_openai_vector_store_file_batch_create_and_retrieve( name="batch_test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -1178,8 +1254,9 @@ def test_openai_vector_store_file_batch_create_and_retrieve( assert retrieved_batch.status == "completed" # Should be completed after processing +@vector_provider_wrapper def test_openai_vector_store_file_batch_list_files( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test listing files in a vector store file batch.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -1191,6 +1268,7 @@ def test_openai_vector_store_file_batch_list_files( name="batch_list_test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -1271,8 +1349,9 @@ def test_openai_vector_store_file_batch_list_files( assert first_page_ids.isdisjoint(second_page_ids) +@vector_provider_wrapper def test_openai_vector_store_file_batch_cancel( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test cancelling a vector store file batch.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -1284,6 +1363,7 @@ def test_openai_vector_store_file_batch_cancel( name="batch_cancel_test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -1326,8 +1406,9 @@ def test_openai_vector_store_file_batch_cancel( assert final_batch.status in ["completed", "cancelled"] +@vector_provider_wrapper def test_openai_vector_store_file_batch_retrieve_contents( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test retrieving file contents after file batch processing.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -1339,6 +1420,7 @@ def test_openai_vector_store_file_batch_retrieve_contents( name="batch_contents_test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -1399,8 +1481,9 @@ def test_openai_vector_store_file_batch_retrieve_contents( assert file_data[i][1].decode("utf-8") in content_text +@vector_provider_wrapper def test_openai_vector_store_file_batch_error_handling( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test error handling for file batch operations.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -1412,6 +1495,7 @@ def test_openai_vector_store_file_batch_error_handling( name="batch_error_test_store", extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) @@ -1443,11 +1527,11 @@ def test_openai_vector_store_file_batch_error_handling( batch_id="non_existent_batch_id", ) - # Test operations on non-existent vector store (returns NotFoundError) + # Test operations on non-existent vector store (returns BadRequestError) if isinstance(compat_client, LlamaStackAsLibraryClient): vector_store_errors = ValueError else: - vector_store_errors = (NotFoundError, OpenAINotFoundError) + vector_store_errors = (BadRequestError, OpenAIBadRequestError) with pytest.raises(vector_store_errors): # Should raise an error for non-existent vector store compat_client.vector_stores.file_batches.create( @@ -1456,8 +1540,9 @@ def test_openai_vector_store_file_batch_error_handling( ) +@vector_provider_wrapper def test_openai_vector_store_embedding_config_from_metadata( - compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension + compat_client_with_empty_stores, client_with_models, embedding_model_id, embedding_dimension, vector_io_provider_id ): """Test that embedding configuration works from metadata source.""" skip_if_provider_doesnt_support_openai_vector_stores(client_with_models) @@ -1471,6 +1556,9 @@ def test_openai_vector_store_embedding_config_from_metadata( "embedding_dimension": str(embedding_dimension), "test_source": "metadata", }, + extra_body={ + "provider_id": vector_io_provider_id, + }, ) assert vector_store_metadata is not None @@ -1489,6 +1577,7 @@ def test_openai_vector_store_embedding_config_from_metadata( extra_body={ "embedding_model": embedding_model_id, "embedding_dimension": int(embedding_dimension), # Ensure same type/value + "provider_id": vector_io_provider_id, }, ) diff --git a/tests/integration/vector_io/test_vector_io.py b/tests/integration/vector_io/test_vector_io.py index 653299338..1f67ddb24 100644 --- a/tests/integration/vector_io/test_vector_io.py +++ b/tests/integration/vector_io/test_vector_io.py @@ -8,6 +8,8 @@ import pytest from llama_stack.apis.vector_io import Chunk +from ..conftest import vector_provider_wrapper + @pytest.fixture(scope="session") def sample_chunks(): @@ -46,45 +48,51 @@ def client_with_empty_registry(client_with_models): clear_registry() -def test_vector_db_retrieve(client_with_empty_registry, embedding_model_id, embedding_dimension): - vector_db_name = "test_vector_db" +@vector_provider_wrapper +def test_vector_store_retrieve( + client_with_empty_registry, embedding_model_id, embedding_dimension, vector_io_provider_id +): + vector_store_name = "test_vector_store" create_response = client_with_empty_registry.vector_stores.create( - name=vector_db_name, + name=vector_store_name, extra_body={ - "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) - actual_vector_db_id = create_response.id + actual_vector_store_id = create_response.id # Retrieve the vector store and validate its properties - response = client_with_empty_registry.vector_stores.retrieve(vector_store_id=actual_vector_db_id) + response = client_with_empty_registry.vector_stores.retrieve(vector_store_id=actual_vector_store_id) assert response is not None - assert response.id == actual_vector_db_id - assert response.name == vector_db_name + assert response.id == actual_vector_store_id + assert response.name == vector_store_name assert response.id.startswith("vs_") -def test_vector_db_register(client_with_empty_registry, embedding_model_id, embedding_dimension): - vector_db_name = "test_vector_db" +@vector_provider_wrapper +def test_vector_store_register( + client_with_empty_registry, embedding_model_id, embedding_dimension, vector_io_provider_id +): + vector_store_name = "test_vector_store" response = client_with_empty_registry.vector_stores.create( - name=vector_db_name, + name=vector_store_name, extra_body={ - "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) - actual_vector_db_id = response.id - assert actual_vector_db_id.startswith("vs_") - assert actual_vector_db_id != vector_db_name + actual_vector_store_id = response.id + assert actual_vector_store_id.startswith("vs_") + assert actual_vector_store_id != vector_store_name vector_stores = client_with_empty_registry.vector_stores.list() assert len(vector_stores.data) == 1 vector_store = vector_stores.data[0] - assert vector_store.id == actual_vector_db_id - assert vector_store.name == vector_db_name + assert vector_store.id == actual_vector_store_id + assert vector_store.name == vector_store_name - client_with_empty_registry.vector_stores.delete(vector_store_id=actual_vector_db_id) + client_with_empty_registry.vector_stores.delete(vector_store_id=actual_vector_store_id) vector_stores = client_with_empty_registry.vector_stores.list() assert len(vector_stores.data) == 0 @@ -100,24 +108,27 @@ def test_vector_db_register(client_with_empty_registry, embedding_model_id, embe ("How does machine learning improve over time?", "doc2"), ], ) -def test_insert_chunks(client_with_empty_registry, embedding_model_id, embedding_dimension, sample_chunks, test_case): - vector_db_name = "test_vector_db" +@vector_provider_wrapper +def test_insert_chunks( + client_with_empty_registry, embedding_model_id, embedding_dimension, sample_chunks, test_case, vector_io_provider_id +): + vector_store_name = "test_vector_store" create_response = client_with_empty_registry.vector_stores.create( - name=vector_db_name, + name=vector_store_name, extra_body={ - "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) - actual_vector_db_id = create_response.id + actual_vector_store_id = create_response.id client_with_empty_registry.vector_io.insert( - vector_db_id=actual_vector_db_id, + vector_db_id=actual_vector_store_id, chunks=sample_chunks, ) response = client_with_empty_registry.vector_io.query( - vector_db_id=actual_vector_db_id, + vector_db_id=actual_vector_store_id, query="What is the capital of France?", ) assert response is not None @@ -126,7 +137,7 @@ def test_insert_chunks(client_with_empty_registry, embedding_model_id, embedding query, expected_doc_id = test_case response = client_with_empty_registry.vector_io.query( - vector_db_id=actual_vector_db_id, + vector_db_id=actual_vector_store_id, query=query, ) assert response is not None @@ -135,21 +146,24 @@ def test_insert_chunks(client_with_empty_registry, embedding_model_id, embedding assert top_match.metadata["document_id"] == expected_doc_id, f"Query '{query}' should match {expected_doc_id}" -def test_insert_chunks_with_precomputed_embeddings(client_with_empty_registry, embedding_model_id, embedding_dimension): +@vector_provider_wrapper +def test_insert_chunks_with_precomputed_embeddings( + client_with_empty_registry, embedding_model_id, embedding_dimension, vector_io_provider_id +): vector_io_provider_params_dict = { "inline::milvus": {"score_threshold": -1.0}, "inline::qdrant": {"score_threshold": -1.0}, "remote::qdrant": {"score_threshold": -1.0}, } - vector_db_name = "test_precomputed_embeddings_db" + vector_store_name = "test_precomputed_embeddings_db" register_response = client_with_empty_registry.vector_stores.create( - name=vector_db_name, + name=vector_store_name, extra_body={ - "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) - actual_vector_db_id = register_response.id + actual_vector_store_id = register_response.id chunks_with_embeddings = [ Chunk( @@ -160,13 +174,13 @@ def test_insert_chunks_with_precomputed_embeddings(client_with_empty_registry, e ] client_with_empty_registry.vector_io.insert( - vector_db_id=actual_vector_db_id, + vector_db_id=actual_vector_store_id, chunks=chunks_with_embeddings, ) provider = [p.provider_id for p in client_with_empty_registry.providers.list() if p.api == "vector_io"][0] response = client_with_empty_registry.vector_io.query( - vector_db_id=actual_vector_db_id, + vector_db_id=actual_vector_store_id, query="precomputed embedding test", params=vector_io_provider_params_dict.get(provider, None), ) @@ -181,23 +195,25 @@ def test_insert_chunks_with_precomputed_embeddings(client_with_empty_registry, e # expect this test to fail +@vector_provider_wrapper def test_query_returns_valid_object_when_identical_to_embedding_in_vdb( - client_with_empty_registry, embedding_model_id, embedding_dimension + client_with_empty_registry, embedding_model_id, embedding_dimension, vector_io_provider_id ): vector_io_provider_params_dict = { "inline::milvus": {"score_threshold": 0.0}, "remote::qdrant": {"score_threshold": 0.0}, "inline::qdrant": {"score_threshold": 0.0}, } - vector_db_name = "test_precomputed_embeddings_db" + vector_store_name = "test_precomputed_embeddings_db" register_response = client_with_empty_registry.vector_stores.create( - name=vector_db_name, + name=vector_store_name, extra_body={ "embedding_model": embedding_model_id, + "provider_id": vector_io_provider_id, }, ) - actual_vector_db_id = register_response.id + actual_vector_store_id = register_response.id chunks_with_embeddings = [ Chunk( @@ -208,13 +224,13 @@ def test_query_returns_valid_object_when_identical_to_embedding_in_vdb( ] client_with_empty_registry.vector_io.insert( - vector_db_id=actual_vector_db_id, + vector_db_id=actual_vector_store_id, chunks=chunks_with_embeddings, ) provider = [p.provider_id for p in client_with_empty_registry.providers.list() if p.api == "vector_io"][0] response = client_with_empty_registry.vector_io.query( - vector_db_id=actual_vector_db_id, + vector_db_id=actual_vector_store_id, query="duplicate", params=vector_io_provider_params_dict.get(provider, None), ) @@ -226,33 +242,44 @@ def test_query_returns_valid_object_when_identical_to_embedding_in_vdb( assert response.chunks[0].metadata["source"] == "precomputed" -def test_auto_extract_embedding_dimension(client_with_empty_registry, embedding_model_id): +@vector_provider_wrapper +def test_auto_extract_embedding_dimension( + client_with_empty_registry, embedding_model_id, embedding_dimension, vector_io_provider_id +): + # This test specifically tests embedding model override, so we keep embedding_model vs = client_with_empty_registry.vector_stores.create( - name="test_auto_extract", extra_body={"embedding_model": embedding_model_id} + name="test_auto_extract", + extra_body={"embedding_model": embedding_model_id, "provider_id": vector_io_provider_id}, ) assert vs.id is not None -def test_provider_auto_selection_single_provider(client_with_empty_registry, embedding_model_id): +@vector_provider_wrapper +def test_provider_auto_selection_single_provider( + client_with_empty_registry, embedding_model_id, embedding_dimension, vector_io_provider_id +): providers = [p for p in client_with_empty_registry.providers.list() if p.api == "vector_io"] if len(providers) != 1: pytest.skip(f"Test requires exactly one vector_io provider, found {len(providers)}") - vs = client_with_empty_registry.vector_stores.create( - name="test_auto_provider", extra_body={"embedding_model": embedding_model_id} - ) + # Test that when only one provider is available, it's auto-selected (no provider_id needed) + vs = client_with_empty_registry.vector_stores.create(name="test_auto_provider") assert vs.id is not None -def test_provider_id_override(client_with_empty_registry, embedding_model_id): +@vector_provider_wrapper +def test_provider_id_override( + client_with_empty_registry, embedding_model_id, embedding_dimension, vector_io_provider_id +): providers = [p for p in client_with_empty_registry.providers.list() if p.api == "vector_io"] if len(providers) != 1: pytest.skip(f"Test requires exactly one vector_io provider, found {len(providers)}") provider_id = providers[0].provider_id + # Test explicit provider_id specification (using default embedding model) vs = client_with_empty_registry.vector_stores.create( - name="test_provider_override", extra_body={"embedding_model": embedding_model_id, "provider_id": provider_id} + name="test_provider_override", extra_body={"provider_id": provider_id} ) assert vs.id is not None assert vs.metadata.get("provider_id") == provider_id diff --git a/tests/unit/cli/test_stack_config.py b/tests/unit/cli/test_stack_config.py index daaf229e5..7b9f3ca0c 100644 --- a/tests/unit/cli/test_stack_config.py +++ b/tests/unit/cli/test_stack_config.py @@ -23,6 +23,27 @@ def config_with_image_name_int(): image_name: 1234 apis_to_serve: [] built_at: {datetime.now().isoformat()} + storage: + backends: + kv_default: + type: kv_sqlite + db_path: /tmp/test_kv.db + sql_default: + type: sql_sqlite + db_path: /tmp/test_sql.db + stores: + metadata: + backend: kv_default + namespace: metadata + inference: + backend: sql_default + table_name: inference + conversations: + backend: sql_default + table_name: conversations + responses: + backend: sql_default + table_name: responses providers: inference: - provider_id: provider1 @@ -54,6 +75,27 @@ def up_to_date_config(): image_name: foo apis_to_serve: [] built_at: {datetime.now().isoformat()} + storage: + backends: + kv_default: + type: kv_sqlite + db_path: /tmp/test_kv.db + sql_default: + type: sql_sqlite + db_path: /tmp/test_sql.db + stores: + metadata: + backend: kv_default + namespace: metadata + inference: + backend: sql_default + table_name: inference + conversations: + backend: sql_default + table_name: conversations + responses: + backend: sql_default + table_name: responses providers: inference: - provider_id: provider1 diff --git a/tests/unit/conversations/test_conversations.py b/tests/unit/conversations/test_conversations.py index 65c3e2333..ff6dd243d 100644 --- a/tests/unit/conversations/test_conversations.py +++ b/tests/unit/conversations/test_conversations.py @@ -20,7 +20,14 @@ from llama_stack.core.conversations.conversations import ( ConversationServiceConfig, ConversationServiceImpl, ) -from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig +from llama_stack.core.datatypes import StackRunConfig +from llama_stack.core.storage.datatypes import ( + ServerStoresConfig, + SqliteSqlStoreConfig, + SqlStoreReference, + StorageConfig, +) +from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends @pytest.fixture @@ -28,7 +35,18 @@ async def service(): with tempfile.TemporaryDirectory() as tmpdir: db_path = Path(tmpdir) / "test_conversations.db" - config = ConversationServiceConfig(conversations_store=SqliteSqlStoreConfig(db_path=str(db_path)), policy=[]) + storage = StorageConfig( + backends={ + "sql_test": SqliteSqlStoreConfig(db_path=str(db_path)), + }, + stores=ServerStoresConfig( + conversations=SqlStoreReference(backend="sql_test", table_name="openai_conversations"), + ), + ) + register_sqlstore_backends({"sql_test": storage.backends["sql_test"]}) + run_config = StackRunConfig(image_name="test", apis=[], providers={}, storage=storage) + + config = ConversationServiceConfig(run_config=run_config, policy=[]) service = ConversationServiceImpl(config, {}) await service.initialize() yield service @@ -121,9 +139,18 @@ async def test_policy_configuration(): AccessRule(forbid=Scope(principal="test_user", actions=[Action.CREATE, Action.READ], resource="*")) ] - config = ConversationServiceConfig( - conversations_store=SqliteSqlStoreConfig(db_path=str(db_path)), policy=restrictive_policy + storage = StorageConfig( + backends={ + "sql_test": SqliteSqlStoreConfig(db_path=str(db_path)), + }, + stores=ServerStoresConfig( + conversations=SqlStoreReference(backend="sql_test", table_name="openai_conversations"), + ), ) + register_sqlstore_backends({"sql_test": storage.backends["sql_test"]}) + run_config = StackRunConfig(image_name="test", apis=[], providers={}, storage=storage) + + config = ConversationServiceConfig(run_config=run_config, policy=restrictive_policy) service = ConversationServiceImpl(config, {}) await service.initialize() diff --git a/tests/unit/core/routers/test_vector_io.py b/tests/unit/core/routers/test_vector_io.py index 997df0d78..dd3246cb3 100644 --- a/tests/unit/core/routers/test_vector_io.py +++ b/tests/unit/core/routers/test_vector_io.py @@ -21,7 +21,7 @@ async def test_single_provider_auto_selection(): Mock(identifier="all-MiniLM-L6-v2", model_type="embedding", metadata={"embedding_dimension": 384}) ] ) - mock_routing_table.register_vector_db = AsyncMock( + mock_routing_table.register_vector_store = AsyncMock( return_value=Mock(identifier="vs_123", provider_id="inline::faiss", provider_resource_id="vs_123") ) mock_routing_table.get_provider_impl = AsyncMock( diff --git a/tests/unit/core/test_stack_validation.py b/tests/unit/core/test_stack_validation.py index 5fc27e199..fa5348d1c 100644 --- a/tests/unit/core/test_stack_validation.py +++ b/tests/unit/core/test_stack_validation.py @@ -4,90 +4,64 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. -""" -Unit tests for Stack validation functions. -""" +"""Unit tests for Stack validation functions.""" from unittest.mock import AsyncMock import pytest -from llama_stack.apis.models import Model, ModelType -from llama_stack.core.stack import validate_default_embedding_model +from llama_stack.apis.models import ListModelsResponse, Model, ModelType +from llama_stack.core.datatypes import QualifiedModel, StackRunConfig, StorageConfig, VectorStoresConfig +from llama_stack.core.stack import validate_vector_stores_config from llama_stack.providers.datatypes import Api -class TestStackValidation: - """Test Stack validation functions.""" +class TestVectorStoresValidation: + async def test_validate_missing_model(self): + """Test validation fails when model not found.""" + run_config = StackRunConfig( + image_name="test", + providers={}, + storage=StorageConfig(backends={}, stores={}), + vector_stores=VectorStoresConfig( + default_provider_id="faiss", + default_embedding_model=QualifiedModel( + provider_id="p", + model_id="missing", + ), + ), + ) + mock_models = AsyncMock() + mock_models.list_models.return_value = ListModelsResponse(data=[]) - @pytest.mark.parametrize( - "models,should_raise", - [ - ([], False), # No models - ( - [ - Model( - identifier="emb1", - model_type=ModelType.embedding, - metadata={"default_configured": True}, - provider_id="p", - provider_resource_id="emb1", - ) - ], - False, - ), # Single default - ( - [ - Model( - identifier="emb1", - model_type=ModelType.embedding, - metadata={"default_configured": True}, - provider_id="p", - provider_resource_id="emb1", - ), - Model( - identifier="emb2", - model_type=ModelType.embedding, - metadata={"default_configured": True}, - provider_id="p", - provider_resource_id="emb2", - ), - ], - True, - ), # Multiple defaults - ( - [ - Model( - identifier="emb1", - model_type=ModelType.embedding, - metadata={"default_configured": True}, - provider_id="p", - provider_resource_id="emb1", - ), - Model( - identifier="llm1", - model_type=ModelType.llm, - metadata={"default_configured": True}, - provider_id="p", - provider_resource_id="llm1", - ), - ], - False, - ), # Ignores non-embedding - ], - ) - async def test_validate_default_embedding_model(self, models, should_raise): - """Test validation with various model configurations.""" - mock_models_impl = AsyncMock() - mock_models_impl.list_models.return_value = models - impls = {Api.models: mock_models_impl} + with pytest.raises(ValueError, match="not found"): + await validate_vector_stores_config(run_config.vector_stores, {Api.models: mock_models}) - if should_raise: - with pytest.raises(ValueError, match="Multiple embedding models marked as default_configured=True"): - await validate_default_embedding_model(impls) - else: - await validate_default_embedding_model(impls) + async def test_validate_success(self): + """Test validation passes with valid model.""" + run_config = StackRunConfig( + image_name="test", + providers={}, + storage=StorageConfig(backends={}, stores={}), + vector_stores=VectorStoresConfig( + default_provider_id="faiss", + default_embedding_model=QualifiedModel( + provider_id="p", + model_id="valid", + ), + ), + ) + mock_models = AsyncMock() + mock_models.list_models.return_value = ListModelsResponse( + data=[ + Model( + identifier="p/valid", # Must match provider_id/model_id format + model_type=ModelType.embedding, + metadata={"embedding_dimension": 768}, + provider_id="p", + provider_resource_id="valid", + ) + ] + ) - async def test_validate_default_embedding_model_no_models_api(self): - """Test validation when models API is not available.""" - await validate_default_embedding_model({}) + await validate_vector_stores_config(run_config.vector_stores, {Api.models: mock_models}) diff --git a/tests/unit/core/test_storage_references.py b/tests/unit/core/test_storage_references.py new file mode 100644 index 000000000..7bceba74d --- /dev/null +++ b/tests/unit/core/test_storage_references.py @@ -0,0 +1,84 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. +# All rights reserved. +# +# This source code is licensed under the terms described in the LICENSE file in +# the root directory of this source tree. + +"""Unit tests for storage backend/reference validation.""" + +import pytest +from pydantic import ValidationError + +from llama_stack.core.datatypes import ( + LLAMA_STACK_RUN_CONFIG_VERSION, + StackRunConfig, +) +from llama_stack.core.storage.datatypes import ( + InferenceStoreReference, + KVStoreReference, + ServerStoresConfig, + SqliteKVStoreConfig, + SqliteSqlStoreConfig, + SqlStoreReference, + StorageConfig, +) + + +def _base_run_config(**overrides): + metadata_reference = overrides.pop( + "metadata_reference", + KVStoreReference(backend="kv_default", namespace="registry"), + ) + inference_reference = overrides.pop( + "inference_reference", + InferenceStoreReference(backend="sql_default", table_name="inference"), + ) + conversations_reference = overrides.pop( + "conversations_reference", + SqlStoreReference(backend="sql_default", table_name="conversations"), + ) + storage = overrides.pop( + "storage", + StorageConfig( + backends={ + "kv_default": SqliteKVStoreConfig(db_path="/tmp/kv.db"), + "sql_default": SqliteSqlStoreConfig(db_path="/tmp/sql.db"), + }, + stores=ServerStoresConfig( + metadata=metadata_reference, + inference=inference_reference, + conversations=conversations_reference, + ), + ), + ) + return StackRunConfig( + version=LLAMA_STACK_RUN_CONFIG_VERSION, + image_name="test-distro", + apis=[], + providers={}, + storage=storage, + **overrides, + ) + + +def test_references_require_known_backend(): + with pytest.raises(ValidationError, match="unknown backend 'missing'"): + _base_run_config(metadata_reference=KVStoreReference(backend="missing", namespace="registry")) + + +def test_references_must_match_backend_family(): + with pytest.raises(ValidationError, match="kv_.* is required"): + _base_run_config(metadata_reference=KVStoreReference(backend="sql_default", namespace="registry")) + + with pytest.raises(ValidationError, match="sql_.* is required"): + _base_run_config( + inference_reference=InferenceStoreReference(backend="kv_default", table_name="inference"), + ) + + +def test_valid_configuration_passes_validation(): + config = _base_run_config() + stores = config.storage.stores + assert stores.metadata is not None and stores.metadata.backend == "kv_default" + assert stores.inference is not None and stores.inference.backend == "sql_default" + assert stores.conversations is not None and stores.conversations.backend == "sql_default" diff --git a/tests/unit/distribution/test_build_path.py b/tests/unit/distribution/test_build_path.py deleted file mode 100644 index 52a71286b..000000000 --- a/tests/unit/distribution/test_build_path.py +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) Meta Platforms, Inc. and affiliates. -# All rights reserved. -# -# This source code is licensed under the terms described in the LICENSE file in -# the root directory of this source tree. - -from pathlib import Path - -from llama_stack.cli.stack._build import ( - _run_stack_build_command_from_build_config, -) -from llama_stack.core.datatypes import BuildConfig, DistributionSpec -from llama_stack.core.utils.image_types import LlamaStackImageType - - -def test_container_build_passes_path(monkeypatch, tmp_path): - called_with = {} - - def spy_build_image(build_config, image_name, distro_or_config, run_config=None): - called_with["path"] = distro_or_config - called_with["run_config"] = run_config - return 0 - - monkeypatch.setattr( - "llama_stack.cli.stack._build.build_image", - spy_build_image, - raising=True, - ) - - cfg = BuildConfig( - image_type=LlamaStackImageType.CONTAINER.value, - distribution_spec=DistributionSpec(providers={}, description=""), - ) - - _run_stack_build_command_from_build_config(cfg, image_name="dummy") - - assert "path" in called_with - assert isinstance(called_with["path"], str) - assert Path(called_with["path"]).exists() - assert called_with["run_config"] is None diff --git a/tests/unit/distribution/test_distribution.py b/tests/unit/distribution/test_distribution.py index 08a376008..3b0643a13 100644 --- a/tests/unit/distribution/test_distribution.py +++ b/tests/unit/distribution/test_distribution.py @@ -13,6 +13,15 @@ from pydantic import BaseModel, Field, ValidationError from llama_stack.core.datatypes import Api, Provider, StackRunConfig from llama_stack.core.distribution import INTERNAL_APIS, get_provider_registry, providable_apis +from llama_stack.core.storage.datatypes import ( + InferenceStoreReference, + KVStoreReference, + ServerStoresConfig, + SqliteKVStoreConfig, + SqliteSqlStoreConfig, + SqlStoreReference, + StorageConfig, +) from llama_stack.providers.datatypes import ProviderSpec @@ -29,6 +38,32 @@ class SampleConfig(BaseModel): } +def _default_storage() -> StorageConfig: + return StorageConfig( + backends={ + "kv_default": SqliteKVStoreConfig(db_path=":memory:"), + "sql_default": SqliteSqlStoreConfig(db_path=":memory:"), + }, + stores=ServerStoresConfig( + metadata=KVStoreReference(backend="kv_default", namespace="registry"), + inference=InferenceStoreReference(backend="sql_default", table_name="inference_store"), + conversations=SqlStoreReference(backend="sql_default", table_name="conversations"), + ), + ) + + +def make_stack_config(**overrides) -> StackRunConfig: + storage = overrides.pop("storage", _default_storage()) + defaults = dict( + image_name="test_image", + apis=[], + providers={}, + storage=storage, + ) + defaults.update(overrides) + return StackRunConfig(**defaults) + + @pytest.fixture def mock_providers(): """Mock the available_providers function to return test providers.""" @@ -47,8 +82,8 @@ def mock_providers(): @pytest.fixture def base_config(tmp_path): """Create a base StackRunConfig with common settings.""" - return StackRunConfig( - image_name="test_image", + return make_stack_config( + apis=["inference"], providers={ "inference": [ Provider( @@ -222,8 +257,8 @@ class TestProviderRegistry: def test_missing_directory(self, mock_providers): """Test handling of missing external providers directory.""" - config = StackRunConfig( - image_name="test_image", + config = make_stack_config( + apis=["inference"], providers={ "inference": [ Provider( @@ -278,7 +313,6 @@ pip_packages: """Test loading an external provider from a module (success path).""" from types import SimpleNamespace - from llama_stack.core.datatypes import Provider, StackRunConfig from llama_stack.providers.datatypes import Api, ProviderSpec # Simulate a provider module with get_provider_spec @@ -293,7 +327,7 @@ pip_packages: import_module_side_effect = make_import_module_side_effect(external_module=fake_module) with patch("importlib.import_module", side_effect=import_module_side_effect) as mock_import: - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ @@ -317,12 +351,11 @@ pip_packages: def test_external_provider_from_module_not_found(self, mock_providers): """Test handling ModuleNotFoundError for missing provider module.""" - from llama_stack.core.datatypes import Provider, StackRunConfig import_module_side_effect = make_import_module_side_effect(raise_for_external=True) with patch("importlib.import_module", side_effect=import_module_side_effect): - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ @@ -341,12 +374,11 @@ pip_packages: def test_external_provider_from_module_missing_get_provider_spec(self, mock_providers): """Test handling missing get_provider_spec in provider module (should raise ValueError).""" - from llama_stack.core.datatypes import Provider, StackRunConfig import_module_side_effect = make_import_module_side_effect(missing_get_provider_spec=True) with patch("importlib.import_module", side_effect=import_module_side_effect): - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ @@ -399,13 +431,12 @@ class TestGetExternalProvidersFromModule: def test_stackrunconfig_provider_without_module(self, mock_providers): """Test that providers without module attribute are skipped.""" - from llama_stack.core.datatypes import Provider, StackRunConfig from llama_stack.core.distribution import get_external_providers_from_module import_module_side_effect = make_import_module_side_effect() with patch("importlib.import_module", side_effect=import_module_side_effect): - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ @@ -426,7 +457,6 @@ class TestGetExternalProvidersFromModule: """Test provider with module containing version spec (e.g., package==1.0.0).""" from types import SimpleNamespace - from llama_stack.core.datatypes import Provider, StackRunConfig from llama_stack.core.distribution import get_external_providers_from_module from llama_stack.providers.datatypes import ProviderSpec @@ -444,7 +474,7 @@ class TestGetExternalProvidersFromModule: raise ModuleNotFoundError(name) with patch("importlib.import_module", side_effect=import_side_effect): - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ @@ -564,7 +594,6 @@ class TestGetExternalProvidersFromModule: """Test when get_provider_spec returns a list of specs.""" from types import SimpleNamespace - from llama_stack.core.datatypes import Provider, StackRunConfig from llama_stack.core.distribution import get_external_providers_from_module from llama_stack.providers.datatypes import ProviderSpec @@ -589,7 +618,7 @@ class TestGetExternalProvidersFromModule: raise ModuleNotFoundError(name) with patch("importlib.import_module", side_effect=import_side_effect): - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ @@ -613,7 +642,6 @@ class TestGetExternalProvidersFromModule: """Test that list return filters specs by provider_type.""" from types import SimpleNamespace - from llama_stack.core.datatypes import Provider, StackRunConfig from llama_stack.core.distribution import get_external_providers_from_module from llama_stack.providers.datatypes import ProviderSpec @@ -638,7 +666,7 @@ class TestGetExternalProvidersFromModule: raise ModuleNotFoundError(name) with patch("importlib.import_module", side_effect=import_side_effect): - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ @@ -662,7 +690,6 @@ class TestGetExternalProvidersFromModule: """Test that list return adds multiple different provider_types when config requests them.""" from types import SimpleNamespace - from llama_stack.core.datatypes import Provider, StackRunConfig from llama_stack.core.distribution import get_external_providers_from_module from llama_stack.providers.datatypes import ProviderSpec @@ -688,7 +715,7 @@ class TestGetExternalProvidersFromModule: raise ModuleNotFoundError(name) with patch("importlib.import_module", side_effect=import_side_effect): - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ @@ -718,7 +745,6 @@ class TestGetExternalProvidersFromModule: def test_module_not_found_raises_value_error(self, mock_providers): """Test that ModuleNotFoundError raises ValueError with helpful message.""" - from llama_stack.core.datatypes import Provider, StackRunConfig from llama_stack.core.distribution import get_external_providers_from_module def import_side_effect(name): @@ -727,7 +753,7 @@ class TestGetExternalProvidersFromModule: raise ModuleNotFoundError(name) with patch("importlib.import_module", side_effect=import_side_effect): - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ @@ -751,7 +777,6 @@ class TestGetExternalProvidersFromModule: """Test that generic exceptions are properly raised.""" from types import SimpleNamespace - from llama_stack.core.datatypes import Provider, StackRunConfig from llama_stack.core.distribution import get_external_providers_from_module def bad_spec(): @@ -765,7 +790,7 @@ class TestGetExternalProvidersFromModule: raise ModuleNotFoundError(name) with patch("importlib.import_module", side_effect=import_side_effect): - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ @@ -787,10 +812,9 @@ class TestGetExternalProvidersFromModule: def test_empty_provider_list(self, mock_providers): """Test with empty provider list.""" - from llama_stack.core.datatypes import StackRunConfig from llama_stack.core.distribution import get_external_providers_from_module - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={}, ) @@ -805,7 +829,6 @@ class TestGetExternalProvidersFromModule: """Test multiple APIs with providers.""" from types import SimpleNamespace - from llama_stack.core.datatypes import Provider, StackRunConfig from llama_stack.core.distribution import get_external_providers_from_module from llama_stack.providers.datatypes import ProviderSpec @@ -830,7 +853,7 @@ class TestGetExternalProvidersFromModule: raise ModuleNotFoundError(name) with patch("importlib.import_module", side_effect=import_side_effect): - config = StackRunConfig( + config = make_stack_config( image_name="test_image", providers={ "inference": [ diff --git a/tests/unit/files/test_files.py b/tests/unit/files/test_files.py index e14e033b9..426e2cf64 100644 --- a/tests/unit/files/test_files.py +++ b/tests/unit/files/test_files.py @@ -11,11 +11,12 @@ from llama_stack.apis.common.errors import ResourceNotFoundError from llama_stack.apis.common.responses import Order from llama_stack.apis.files import OpenAIFilePurpose from llama_stack.core.access_control.access_control import default_policy +from llama_stack.core.storage.datatypes import SqliteSqlStoreConfig, SqlStoreReference from llama_stack.providers.inline.files.localfs import ( LocalfsFilesImpl, LocalfsFilesImplConfig, ) -from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig +from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends class MockUploadFile: @@ -36,8 +37,11 @@ async def files_provider(tmp_path): storage_dir = tmp_path / "files" db_path = tmp_path / "files_metadata.db" + backend_name = "sql_localfs_test" + register_sqlstore_backends({backend_name: SqliteSqlStoreConfig(db_path=db_path.as_posix())}) config = LocalfsFilesImplConfig( - storage_dir=storage_dir.as_posix(), metadata_store=SqliteSqlStoreConfig(db_path=db_path.as_posix()) + storage_dir=storage_dir.as_posix(), + metadata_store=SqlStoreReference(backend=backend_name, table_name="files_metadata"), ) provider = LocalfsFilesImpl(config, default_policy()) diff --git a/tests/unit/prompts/prompts/conftest.py b/tests/unit/prompts/prompts/conftest.py index b2c619e49..fe30e1a77 100644 --- a/tests/unit/prompts/prompts/conftest.py +++ b/tests/unit/prompts/prompts/conftest.py @@ -9,7 +9,16 @@ import random import pytest from llama_stack.core.prompts.prompts import PromptServiceConfig, PromptServiceImpl -from llama_stack.providers.utils.kvstore.config import SqliteKVStoreConfig +from llama_stack.core.storage.datatypes import ( + InferenceStoreReference, + KVStoreReference, + ServerStoresConfig, + SqliteKVStoreConfig, + SqliteSqlStoreConfig, + SqlStoreReference, + StorageConfig, +) +from llama_stack.providers.utils.kvstore import kvstore_impl, register_kvstore_backends @pytest.fixture @@ -19,12 +28,28 @@ async def temp_prompt_store(tmp_path_factory): db_path = str(temp_dir / f"{unique_id}.db") from llama_stack.core.datatypes import StackRunConfig - from llama_stack.providers.utils.kvstore import kvstore_impl - mock_run_config = StackRunConfig(image_name="test-distribution", apis=[], providers={}) + storage = StorageConfig( + backends={ + "kv_test": SqliteKVStoreConfig(db_path=db_path), + "sql_test": SqliteSqlStoreConfig(db_path=str(temp_dir / f"{unique_id}_sql.db")), + }, + stores=ServerStoresConfig( + metadata=KVStoreReference(backend="kv_test", namespace="registry"), + inference=InferenceStoreReference(backend="sql_test", table_name="inference"), + conversations=SqlStoreReference(backend="sql_test", table_name="conversations"), + ), + ) + mock_run_config = StackRunConfig( + image_name="test-distribution", + apis=[], + providers={}, + storage=storage, + ) config = PromptServiceConfig(run_config=mock_run_config) store = PromptServiceImpl(config, deps={}) - store.kvstore = await kvstore_impl(SqliteKVStoreConfig(db_path=db_path)) + register_kvstore_backends({"kv_test": storage.backends["kv_test"]}) + store.kvstore = await kvstore_impl(KVStoreReference(backend="kv_test", namespace="prompts")) yield store diff --git a/tests/unit/providers/agent/test_meta_reference_agent.py b/tests/unit/providers/agent/test_meta_reference_agent.py index cfb3e1327..dfd9b6d52 100644 --- a/tests/unit/providers/agent/test_meta_reference_agent.py +++ b/tests/unit/providers/agent/test_meta_reference_agent.py @@ -26,6 +26,20 @@ from llama_stack.providers.inline.agents.meta_reference.config import MetaRefere from llama_stack.providers.inline.agents.meta_reference.persistence import AgentInfo +@pytest.fixture(autouse=True) +def setup_backends(tmp_path): + """Register KV and SQL store backends for testing.""" + from llama_stack.core.storage.datatypes import SqliteKVStoreConfig, SqliteSqlStoreConfig + from llama_stack.providers.utils.kvstore.kvstore import register_kvstore_backends + from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends + + kv_path = str(tmp_path / "test_kv.db") + sql_path = str(tmp_path / "test_sql.db") + + register_kvstore_backends({"kv_default": SqliteKVStoreConfig(db_path=kv_path)}) + register_sqlstore_backends({"sql_default": SqliteSqlStoreConfig(db_path=sql_path)}) + + @pytest.fixture def mock_apis(): return { @@ -40,15 +54,20 @@ def mock_apis(): @pytest.fixture def config(tmp_path): + from llama_stack.core.storage.datatypes import KVStoreReference, ResponsesStoreReference + from llama_stack.providers.inline.agents.meta_reference.config import AgentPersistenceConfig + return MetaReferenceAgentsImplConfig( - persistence_store={ - "type": "sqlite", - "db_path": str(tmp_path / "test.db"), - }, - responses_store={ - "type": "sqlite", - "db_path": str(tmp_path / "test.db"), - }, + persistence=AgentPersistenceConfig( + agent_state=KVStoreReference( + backend="kv_default", + namespace="agents", + ), + responses=ResponsesStoreReference( + backend="sql_default", + table_name="responses", + ), + ) ) diff --git a/tests/unit/providers/agents/meta_reference/test_openai_responses.py b/tests/unit/providers/agents/meta_reference/test_openai_responses.py index e93668a62..f31ec0c28 100644 --- a/tests/unit/providers/agents/meta_reference/test_openai_responses.py +++ b/tests/unit/providers/agents/meta_reference/test_openai_responses.py @@ -42,7 +42,7 @@ from llama_stack.apis.inference import ( ) from llama_stack.apis.tools.tools import ListToolDefsResponse, ToolDef, ToolGroups, ToolInvocationResult, ToolRuntime from llama_stack.core.access_control.access_control import default_policy -from llama_stack.core.datatypes import ResponsesStoreConfig +from llama_stack.core.storage.datatypes import ResponsesStoreReference, SqliteSqlStoreConfig from llama_stack.providers.inline.agents.meta_reference.responses.openai_responses import ( OpenAIResponsesImpl, ) @@ -50,7 +50,7 @@ from llama_stack.providers.utils.responses.responses_store import ( ResponsesStore, _OpenAIResponseObjectWithInputAndMessages, ) -from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig +from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends from tests.unit.providers.agents.meta_reference.fixtures import load_chat_completion_fixture @@ -814,6 +814,69 @@ async def test_create_openai_response_with_instructions_and_previous_response( assert sent_messages[3].content == "Which is the largest?" +async def test_create_openai_response_with_previous_response_instructions( + openai_responses_impl, mock_responses_store, mock_inference_api +): + """Test prepending instructions and previous response with instructions.""" + + input_item_message = OpenAIResponseMessage( + id="123", + content="Name some towns in Ireland", + role="user", + ) + response_output_message = OpenAIResponseMessage( + id="123", + content="Galway, Longford, Sligo", + status="completed", + role="assistant", + ) + response = _OpenAIResponseObjectWithInputAndMessages( + created_at=1, + id="resp_123", + model="fake_model", + output=[response_output_message], + status="completed", + text=OpenAIResponseText(format=OpenAIResponseTextFormat(type="text")), + input=[input_item_message], + messages=[ + OpenAIUserMessageParam(content="Name some towns in Ireland"), + OpenAIAssistantMessageParam(content="Galway, Longford, Sligo"), + ], + instructions="You are a helpful assistant.", + ) + mock_responses_store.get_response_object.return_value = response + + model = "meta-llama/Llama-3.1-8B-Instruct" + instructions = "You are a geography expert. Provide concise answers." + + mock_inference_api.openai_chat_completion.return_value = fake_stream() + + # Execute + await openai_responses_impl.create_openai_response( + input="Which is the largest?", model=model, instructions=instructions, previous_response_id="123" + ) + + # Verify + mock_inference_api.openai_chat_completion.assert_called_once() + call_args = mock_inference_api.openai_chat_completion.call_args + params = call_args.args[0] + sent_messages = params.messages + + # Check that instructions were prepended as a system message + # and that the previous response instructions were not carried over + assert len(sent_messages) == 4, sent_messages + assert sent_messages[0].role == "system" + assert sent_messages[0].content == instructions + + # Check the rest of the messages were converted correctly + assert sent_messages[1].role == "user" + assert sent_messages[1].content == "Name some towns in Ireland" + assert sent_messages[2].role == "assistant" + assert sent_messages[2].content == "Galway, Longford, Sligo" + assert sent_messages[3].role == "user" + assert sent_messages[3].content == "Which is the largest?" + + async def test_list_openai_response_input_items_delegation(openai_responses_impl, mock_responses_store): """Test that list_openai_response_input_items properly delegates to responses_store with correct parameters.""" # Setup @@ -854,8 +917,10 @@ async def test_responses_store_list_input_items_logic(): # Create mock store and response store mock_sql_store = AsyncMock() + backend_name = "sql_responses_test" + register_sqlstore_backends({backend_name: SqliteSqlStoreConfig(db_path="mock_db_path")}) responses_store = ResponsesStore( - ResponsesStoreConfig(sql_store_config=SqliteSqlStoreConfig(db_path="mock_db_path")), policy=default_policy() + ResponsesStoreReference(backend=backend_name, table_name="responses"), policy=default_policy() ) responses_store.sql_store = mock_sql_store diff --git a/tests/unit/providers/batches/conftest.py b/tests/unit/providers/batches/conftest.py index df37141b5..d161bf976 100644 --- a/tests/unit/providers/batches/conftest.py +++ b/tests/unit/providers/batches/conftest.py @@ -12,10 +12,10 @@ from unittest.mock import AsyncMock import pytest +from llama_stack.core.storage.datatypes import KVStoreReference, SqliteKVStoreConfig from llama_stack.providers.inline.batches.reference.batches import ReferenceBatchesImpl from llama_stack.providers.inline.batches.reference.config import ReferenceBatchesImplConfig -from llama_stack.providers.utils.kvstore import kvstore_impl -from llama_stack.providers.utils.kvstore.config import SqliteKVStoreConfig +from llama_stack.providers.utils.kvstore import kvstore_impl, register_kvstore_backends @pytest.fixture @@ -23,8 +23,10 @@ async def provider(): """Create a test provider instance with temporary database.""" with tempfile.TemporaryDirectory() as tmpdir: db_path = Path(tmpdir) / "test_batches.db" + backend_name = "kv_batches_test" kvstore_config = SqliteKVStoreConfig(db_path=str(db_path)) - config = ReferenceBatchesImplConfig(kvstore=kvstore_config) + register_kvstore_backends({backend_name: kvstore_config}) + config = ReferenceBatchesImplConfig(kvstore=KVStoreReference(backend=backend_name, namespace="batches")) # Create kvstore and mock APIs kvstore = await kvstore_impl(config.kvstore) diff --git a/tests/unit/providers/files/conftest.py b/tests/unit/providers/files/conftest.py index 46282e3dc..c64ecc3a3 100644 --- a/tests/unit/providers/files/conftest.py +++ b/tests/unit/providers/files/conftest.py @@ -8,8 +8,9 @@ import boto3 import pytest from moto import mock_aws +from llama_stack.core.storage.datatypes import SqliteSqlStoreConfig, SqlStoreReference from llama_stack.providers.remote.files.s3 import S3FilesImplConfig, get_adapter_impl -from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig +from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends class MockUploadFile: @@ -38,11 +39,13 @@ def sample_text_file2(): def s3_config(tmp_path): db_path = tmp_path / "s3_files_metadata.db" + backend_name = f"sql_s3_{tmp_path.name}" + register_sqlstore_backends({backend_name: SqliteSqlStoreConfig(db_path=db_path.as_posix())}) return S3FilesImplConfig( bucket_name=f"test-bucket-{tmp_path.name}", region="not-a-region", auto_create_bucket=True, - metadata_store=SqliteSqlStoreConfig(db_path=db_path.as_posix()), + metadata_store=SqlStoreReference(backend=backend_name, table_name="s3_files_metadata"), ) diff --git a/tests/unit/providers/vector_io/conftest.py b/tests/unit/providers/vector_io/conftest.py index 8e5c85cf1..2951ca2e5 100644 --- a/tests/unit/providers/vector_io/conftest.py +++ b/tests/unit/providers/vector_io/conftest.py @@ -10,15 +10,16 @@ from unittest.mock import AsyncMock, MagicMock, patch import numpy as np import pytest -from llama_stack.apis.vector_dbs import VectorDB from llama_stack.apis.vector_io import Chunk, ChunkMetadata, QueryChunksResponse +from llama_stack.apis.vector_stores import VectorStore +from llama_stack.core.storage.datatypes import KVStoreReference, SqliteKVStoreConfig from llama_stack.providers.inline.vector_io.faiss.config import FaissVectorIOConfig from llama_stack.providers.inline.vector_io.faiss.faiss import FaissIndex, FaissVectorIOAdapter from llama_stack.providers.inline.vector_io.sqlite_vec import SQLiteVectorIOConfig from llama_stack.providers.inline.vector_io.sqlite_vec.sqlite_vec import SQLiteVecIndex, SQLiteVecVectorIOAdapter from llama_stack.providers.remote.vector_io.pgvector.config import PGVectorVectorIOConfig from llama_stack.providers.remote.vector_io.pgvector.pgvector import PGVectorIndex, PGVectorVectorIOAdapter -from llama_stack.providers.utils.kvstore.config import SqliteKVStoreConfig +from llama_stack.providers.utils.kvstore import register_kvstore_backends EMBEDDING_DIMENSION = 768 COLLECTION_PREFIX = "test_collection" @@ -30,7 +31,7 @@ def vector_provider(request): @pytest.fixture -def vector_db_id() -> str: +def vector_store_id() -> str: return f"test-vector-db-{random.randint(1, 100)}" @@ -112,8 +113,9 @@ async def unique_kvstore_config(tmp_path_factory): unique_id = f"test_kv_{np.random.randint(1e6)}" temp_dir = tmp_path_factory.getbasetemp() db_path = str(temp_dir / f"{unique_id}.db") - - return SqliteKVStoreConfig(db_path=db_path) + backend_name = f"kv_vector_{unique_id}" + register_kvstore_backends({backend_name: SqliteKVStoreConfig(db_path=db_path)}) + return KVStoreReference(backend=backend_name, namespace=f"vector_io::{unique_id}") @pytest.fixture(scope="session") @@ -138,18 +140,17 @@ async def sqlite_vec_vec_index(embedding_dimension, tmp_path_factory): async def sqlite_vec_adapter(sqlite_vec_db_path, unique_kvstore_config, mock_inference_api, embedding_dimension): config = SQLiteVectorIOConfig( db_path=sqlite_vec_db_path, - kvstore=unique_kvstore_config, + persistence=unique_kvstore_config, ) adapter = SQLiteVecVectorIOAdapter( config=config, inference_api=mock_inference_api, files_api=None, - models_api=None, ) collection_id = f"sqlite_test_collection_{np.random.randint(1e6)}" await adapter.initialize() - await adapter.register_vector_db( - VectorDB( + await adapter.register_vector_store( + VectorStore( identifier=collection_id, provider_id="test_provider", embedding_model="test_model", @@ -177,17 +178,16 @@ async def faiss_vec_index(embedding_dimension): @pytest.fixture async def faiss_vec_adapter(unique_kvstore_config, mock_inference_api, embedding_dimension): config = FaissVectorIOConfig( - kvstore=unique_kvstore_config, + persistence=unique_kvstore_config, ) adapter = FaissVectorIOAdapter( config=config, inference_api=mock_inference_api, files_api=None, - models_api=None, ) await adapter.initialize() - await adapter.register_vector_db( - VectorDB( + await adapter.register_vector_store( + VectorStore( identifier=f"faiss_test_collection_{np.random.randint(1e6)}", provider_id="test_provider", embedding_model="test_model", @@ -215,7 +215,7 @@ def mock_psycopg2_connection(): async def pgvector_vec_index(embedding_dimension, mock_psycopg2_connection): connection, cursor = mock_psycopg2_connection - vector_db = VectorDB( + vector_store = VectorStore( identifier="test-vector-db", embedding_model="test-model", embedding_dimension=embedding_dimension, @@ -225,7 +225,7 @@ async def pgvector_vec_index(embedding_dimension, mock_psycopg2_connection): with patch("llama_stack.providers.remote.vector_io.pgvector.pgvector.psycopg2"): with patch("llama_stack.providers.remote.vector_io.pgvector.pgvector.execute_values"): - index = PGVectorIndex(vector_db, embedding_dimension, connection, distance_metric="COSINE") + index = PGVectorIndex(vector_store, embedding_dimension, connection, distance_metric="COSINE") index._test_chunks = [] original_add_chunks = index.add_chunks @@ -253,7 +253,7 @@ async def pgvector_vec_adapter(unique_kvstore_config, mock_inference_api, embedd db="test_db", user="test_user", password="test_password", - kvstore=unique_kvstore_config, + persistence=unique_kvstore_config, ) adapter = PGVectorVectorIOAdapter(config, mock_inference_api, None) @@ -281,30 +281,30 @@ async def pgvector_vec_adapter(unique_kvstore_config, mock_inference_api, embedd await adapter.initialize() adapter.conn = mock_conn - async def mock_insert_chunks(vector_db_id, chunks, ttl_seconds=None): - index = await adapter._get_and_cache_vector_db_index(vector_db_id) + async def mock_insert_chunks(vector_store_id, chunks, ttl_seconds=None): + index = await adapter._get_and_cache_vector_store_index(vector_store_id) if not index: - raise ValueError(f"Vector DB {vector_db_id} not found") + raise ValueError(f"Vector DB {vector_store_id} not found") await index.insert_chunks(chunks) adapter.insert_chunks = mock_insert_chunks - async def mock_query_chunks(vector_db_id, query, params=None): - index = await adapter._get_and_cache_vector_db_index(vector_db_id) + async def mock_query_chunks(vector_store_id, query, params=None): + index = await adapter._get_and_cache_vector_store_index(vector_store_id) if not index: - raise ValueError(f"Vector DB {vector_db_id} not found") + raise ValueError(f"Vector DB {vector_store_id} not found") return await index.query_chunks(query, params) adapter.query_chunks = mock_query_chunks - test_vector_db = VectorDB( + test_vector_store = VectorStore( identifier=f"pgvector_test_collection_{random.randint(1, 1_000_000)}", provider_id="test_provider", embedding_model="test_model", embedding_dimension=embedding_dimension, ) - await adapter.register_vector_db(test_vector_db) - adapter.test_collection_id = test_vector_db.identifier + await adapter.register_vector_store(test_vector_store) + adapter.test_collection_id = test_vector_store.identifier yield adapter await adapter.shutdown() diff --git a/tests/unit/providers/vector_io/test_faiss.py b/tests/unit/providers/vector_io/test_faiss.py index 76969b711..7b870d16e 100644 --- a/tests/unit/providers/vector_io/test_faiss.py +++ b/tests/unit/providers/vector_io/test_faiss.py @@ -11,9 +11,8 @@ import numpy as np import pytest from llama_stack.apis.files import Files -from llama_stack.apis.models import Models -from llama_stack.apis.vector_dbs import VectorDB from llama_stack.apis.vector_io import Chunk, QueryChunksResponse +from llama_stack.apis.vector_stores import VectorStore from llama_stack.providers.datatypes import HealthStatus from llama_stack.providers.inline.vector_io.faiss.config import FaissVectorIOConfig from llama_stack.providers.inline.vector_io.faiss.faiss import ( @@ -44,8 +43,8 @@ def embedding_dimension(): @pytest.fixture -def vector_db_id(): - return "test_vector_db" +def vector_store_id(): + return "test_vector_store" @pytest.fixture @@ -62,12 +61,12 @@ def sample_embeddings(embedding_dimension): @pytest.fixture -def mock_vector_db(vector_db_id, embedding_dimension) -> MagicMock: - mock_vector_db = MagicMock(spec=VectorDB) - mock_vector_db.embedding_model = "mock_embedding_model" - mock_vector_db.identifier = vector_db_id - mock_vector_db.embedding_dimension = embedding_dimension - return mock_vector_db +def mock_vector_store(vector_store_id, embedding_dimension) -> MagicMock: + mock_vector_store = MagicMock(spec=VectorStore) + mock_vector_store.embedding_model = "mock_embedding_model" + mock_vector_store.identifier = vector_store_id + mock_vector_store.embedding_dimension = embedding_dimension + return mock_vector_store @pytest.fixture @@ -76,12 +75,6 @@ def mock_files_api(): return mock_api -@pytest.fixture -def mock_models_api(): - mock_api = MagicMock(spec=Models) - return mock_api - - @pytest.fixture def faiss_config(): config = MagicMock(spec=FaissVectorIOConfig) @@ -117,7 +110,7 @@ async def test_faiss_query_vector_returns_infinity_when_query_and_embedding_are_ assert response.chunks[1] == sample_chunks[1] -async def test_health_success(mock_models_api): +async def test_health_success(): """Test that the health check returns OK status when faiss is working correctly.""" # Create a fresh instance of FaissVectorIOAdapter for testing config = MagicMock() @@ -126,9 +119,7 @@ async def test_health_success(mock_models_api): with patch("llama_stack.providers.inline.vector_io.faiss.faiss.faiss.IndexFlatL2") as mock_index_flat: mock_index_flat.return_value = MagicMock() - adapter = FaissVectorIOAdapter( - config=config, inference_api=inference_api, models_api=mock_models_api, files_api=files_api - ) + adapter = FaissVectorIOAdapter(config=config, inference_api=inference_api, files_api=files_api) # Calling the health method directly response = await adapter.health() @@ -142,7 +133,7 @@ async def test_health_success(mock_models_api): mock_index_flat.assert_called_once_with(128) # VECTOR_DIMENSION is 128 -async def test_health_failure(mock_models_api): +async def test_health_failure(): """Test that the health check returns ERROR status when faiss encounters an error.""" # Create a fresh instance of FaissVectorIOAdapter for testing config = MagicMock() @@ -152,9 +143,7 @@ async def test_health_failure(mock_models_api): with patch("llama_stack.providers.inline.vector_io.faiss.faiss.faiss.IndexFlatL2") as mock_index_flat: mock_index_flat.side_effect = Exception("Test error") - adapter = FaissVectorIOAdapter( - config=config, inference_api=inference_api, models_api=mock_models_api, files_api=files_api - ) + adapter = FaissVectorIOAdapter(config=config, inference_api=inference_api, files_api=files_api) # Calling the health method directly response = await adapter.health() diff --git a/tests/unit/providers/vector_io/test_vector_io_openai_vector_stores.py b/tests/unit/providers/vector_io/test_vector_io_openai_vector_stores.py index 32d59c91b..9d9c767f6 100644 --- a/tests/unit/providers/vector_io/test_vector_io_openai_vector_stores.py +++ b/tests/unit/providers/vector_io/test_vector_io_openai_vector_stores.py @@ -6,14 +6,12 @@ import json import time -from unittest.mock import AsyncMock, Mock, patch +from unittest.mock import AsyncMock, patch import numpy as np import pytest from llama_stack.apis.common.errors import VectorStoreNotFoundError -from llama_stack.apis.models import Model, ModelType -from llama_stack.apis.vector_dbs import VectorDB from llama_stack.apis.vector_io import ( Chunk, OpenAICreateVectorStoreFileBatchRequestWithExtraBody, @@ -22,6 +20,7 @@ from llama_stack.apis.vector_io import ( VectorStoreChunkingStrategyAuto, VectorStoreFileObject, ) +from llama_stack.apis.vector_stores import VectorStore from llama_stack.providers.inline.vector_io.sqlite_vec.sqlite_vec import VECTOR_DBS_PREFIX # This test is a unit test for the inline VectorIO providers. This should only contain @@ -72,7 +71,7 @@ async def test_chunk_id_conflict(vector_index, sample_chunks, embedding_dimensio async def test_initialize_adapter_with_existing_kvstore(vector_io_adapter): key = f"{VECTOR_DBS_PREFIX}db1" - dummy = VectorDB( + dummy = VectorStore( identifier="foo_db", provider_id="test_provider", embedding_model="test_model", embedding_dimension=128 ) await vector_io_adapter.kvstore.set(key=key, value=json.dumps(dummy.model_dump())) @@ -82,10 +81,10 @@ async def test_initialize_adapter_with_existing_kvstore(vector_io_adapter): async def test_persistence_across_adapter_restarts(vector_io_adapter): await vector_io_adapter.initialize() - dummy = VectorDB( + dummy = VectorStore( identifier="foo_db", provider_id="test_provider", embedding_model="test_model", embedding_dimension=128 ) - await vector_io_adapter.register_vector_db(dummy) + await vector_io_adapter.register_vector_store(dummy) await vector_io_adapter.shutdown() await vector_io_adapter.initialize() @@ -93,15 +92,15 @@ async def test_persistence_across_adapter_restarts(vector_io_adapter): await vector_io_adapter.shutdown() -async def test_register_and_unregister_vector_db(vector_io_adapter): +async def test_register_and_unregister_vector_store(vector_io_adapter): unique_id = f"foo_db_{np.random.randint(1e6)}" - dummy = VectorDB( + dummy = VectorStore( identifier=unique_id, provider_id="test_provider", embedding_model="test_model", embedding_dimension=128 ) - await vector_io_adapter.register_vector_db(dummy) + await vector_io_adapter.register_vector_store(dummy) assert dummy.identifier in vector_io_adapter.cache - await vector_io_adapter.unregister_vector_db(dummy.identifier) + await vector_io_adapter.unregister_vector_store(dummy.identifier) assert dummy.identifier not in vector_io_adapter.cache @@ -122,7 +121,7 @@ async def test_insert_chunks_calls_underlying_index(vector_io_adapter): async def test_insert_chunks_missing_db_raises(vector_io_adapter): - vector_io_adapter._get_and_cache_vector_db_index = AsyncMock(return_value=None) + vector_io_adapter._get_and_cache_vector_store_index = AsyncMock(return_value=None) with pytest.raises(ValueError): await vector_io_adapter.insert_chunks("db_not_exist", []) @@ -171,7 +170,7 @@ async def test_query_chunks_calls_underlying_index_and_returns(vector_io_adapter async def test_query_chunks_missing_db_raises(vector_io_adapter): - vector_io_adapter._get_and_cache_vector_db_index = AsyncMock(return_value=None) + vector_io_adapter._get_and_cache_vector_store_index = AsyncMock(return_value=None) with pytest.raises(ValueError): await vector_io_adapter.query_chunks("db_missing", "q", None) @@ -183,7 +182,7 @@ async def test_save_openai_vector_store(vector_io_adapter): "id": store_id, "name": "Test Store", "description": "A test OpenAI vector store", - "vector_db_id": "test_db", + "vector_store_id": "test_db", "embedding_model": "test_model", } @@ -199,7 +198,7 @@ async def test_update_openai_vector_store(vector_io_adapter): "id": store_id, "name": "Test Store", "description": "A test OpenAI vector store", - "vector_db_id": "test_db", + "vector_store_id": "test_db", "embedding_model": "test_model", } @@ -215,7 +214,7 @@ async def test_delete_openai_vector_store(vector_io_adapter): "id": store_id, "name": "Test Store", "description": "A test OpenAI vector store", - "vector_db_id": "test_db", + "vector_store_id": "test_db", "embedding_model": "test_model", } @@ -230,7 +229,7 @@ async def test_load_openai_vector_stores(vector_io_adapter): "id": store_id, "name": "Test Store", "description": "A test OpenAI vector store", - "vector_db_id": "test_db", + "vector_store_id": "test_db", "embedding_model": "test_model", } @@ -996,101 +995,11 @@ async def test_max_concurrent_files_per_batch(vector_io_adapter): assert batch.file_counts.in_progress == 8 -async def test_get_default_embedding_model_success(vector_io_adapter): - """Test successful default embedding model detection.""" - # Mock models API with a default model - mock_models_api = Mock() - mock_models_api.list_models = AsyncMock( - return_value=Mock( - data=[ - Model( - identifier="nomic-embed-text-v1.5", - model_type=ModelType.embedding, - provider_id="test-provider", - metadata={ - "embedding_dimension": 768, - "default_configured": True, - }, - ) - ] - ) - ) - - vector_io_adapter.models_api = mock_models_api - result = await vector_io_adapter._get_default_embedding_model_and_dimension() - - assert result is not None - model_id, dimension = result - assert model_id == "nomic-embed-text-v1.5" - assert dimension == 768 - - -async def test_get_default_embedding_model_multiple_defaults_error(vector_io_adapter): - """Test error when multiple models are marked as default.""" - mock_models_api = Mock() - mock_models_api.list_models = AsyncMock( - return_value=Mock( - data=[ - Model( - identifier="model1", - model_type=ModelType.embedding, - provider_id="test-provider", - metadata={"embedding_dimension": 768, "default_configured": True}, - ), - Model( - identifier="model2", - model_type=ModelType.embedding, - provider_id="test-provider", - metadata={"embedding_dimension": 512, "default_configured": True}, - ), - ] - ) - ) - - vector_io_adapter.models_api = mock_models_api - - with pytest.raises(ValueError, match="Multiple embedding models marked as default_configured=True"): - await vector_io_adapter._get_default_embedding_model_and_dimension() - - -async def test_openai_create_vector_store_uses_default_model(vector_io_adapter): - """Test that vector store creation uses default embedding model when none specified.""" - # Mock models API and dependencies - mock_models_api = Mock() - mock_models_api.list_models = AsyncMock( - return_value=Mock( - data=[ - Model( - identifier="default-model", - model_type=ModelType.embedding, - provider_id="test-provider", - metadata={"embedding_dimension": 512, "default_configured": True}, - ) - ] - ) - ) - - vector_io_adapter.models_api = mock_models_api - vector_io_adapter.register_vector_db = AsyncMock() - vector_io_adapter.__provider_id__ = "test-provider" - - # Create vector store without specifying embedding model - params = OpenAICreateVectorStoreRequestWithExtraBody(name="test-store") - result = await vector_io_adapter.openai_create_vector_store(params) - - # Verify the vector store was created with default model - assert result.name == "test-store" - vector_io_adapter.register_vector_db.assert_called_once() - call_args = vector_io_adapter.register_vector_db.call_args[0][0] - assert call_args.embedding_model == "default-model" - assert call_args.embedding_dimension == 512 - - async def test_embedding_config_from_metadata(vector_io_adapter): """Test that embedding configuration is correctly extracted from metadata.""" - # Mock register_vector_db to avoid actual registration - vector_io_adapter.register_vector_db = AsyncMock() + # Mock register_vector_store to avoid actual registration + vector_io_adapter.register_vector_store = AsyncMock() # Set provider_id attribute for the adapter vector_io_adapter.__provider_id__ = "test_provider" @@ -1106,9 +1015,9 @@ async def test_embedding_config_from_metadata(vector_io_adapter): await vector_io_adapter.openai_create_vector_store(params) - # Verify VectorDB was registered with correct embedding config from metadata - vector_io_adapter.register_vector_db.assert_called_once() - call_args = vector_io_adapter.register_vector_db.call_args[0][0] + # Verify VectorStore was registered with correct embedding config from metadata + vector_io_adapter.register_vector_store.assert_called_once() + call_args = vector_io_adapter.register_vector_store.call_args[0][0] assert call_args.embedding_model == "test-embedding-model" assert call_args.embedding_dimension == 512 @@ -1116,8 +1025,8 @@ async def test_embedding_config_from_metadata(vector_io_adapter): async def test_embedding_config_from_extra_body(vector_io_adapter): """Test that embedding configuration is correctly extracted from extra_body when metadata is empty.""" - # Mock register_vector_db to avoid actual registration - vector_io_adapter.register_vector_db = AsyncMock() + # Mock register_vector_store to avoid actual registration + vector_io_adapter.register_vector_store = AsyncMock() # Set provider_id attribute for the adapter vector_io_adapter.__provider_id__ = "test_provider" @@ -1133,9 +1042,9 @@ async def test_embedding_config_from_extra_body(vector_io_adapter): await vector_io_adapter.openai_create_vector_store(params) - # Verify VectorDB was registered with correct embedding config from extra_body - vector_io_adapter.register_vector_db.assert_called_once() - call_args = vector_io_adapter.register_vector_db.call_args[0][0] + # Verify VectorStore was registered with correct embedding config from extra_body + vector_io_adapter.register_vector_store.assert_called_once() + call_args = vector_io_adapter.register_vector_store.call_args[0][0] assert call_args.embedding_model == "extra-body-model" assert call_args.embedding_dimension == 1024 @@ -1143,8 +1052,8 @@ async def test_embedding_config_from_extra_body(vector_io_adapter): async def test_embedding_config_consistency_check_passes(vector_io_adapter): """Test that consistent embedding config in both metadata and extra_body passes validation.""" - # Mock register_vector_db to avoid actual registration - vector_io_adapter.register_vector_db = AsyncMock() + # Mock register_vector_store to avoid actual registration + vector_io_adapter.register_vector_store = AsyncMock() # Set provider_id attribute for the adapter vector_io_adapter.__provider_id__ = "test_provider" @@ -1164,61 +1073,17 @@ async def test_embedding_config_consistency_check_passes(vector_io_adapter): await vector_io_adapter.openai_create_vector_store(params) # Should not raise any error and use metadata config - vector_io_adapter.register_vector_db.assert_called_once() - call_args = vector_io_adapter.register_vector_db.call_args[0][0] + vector_io_adapter.register_vector_store.assert_called_once() + call_args = vector_io_adapter.register_vector_store.call_args[0][0] assert call_args.embedding_model == "consistent-model" assert call_args.embedding_dimension == 768 -async def test_embedding_config_inconsistency_errors(vector_io_adapter): - """Test that inconsistent embedding config between metadata and extra_body raises errors.""" - - # Mock register_vector_db to avoid actual registration - vector_io_adapter.register_vector_db = AsyncMock() - # Set provider_id attribute for the adapter - vector_io_adapter.__provider_id__ = "test_provider" - - # Test with inconsistent embedding model - params = OpenAICreateVectorStoreRequestWithExtraBody( - name="test_store", - metadata={ - "embedding_model": "metadata-model", - "embedding_dimension": "768", - }, - **{ - "embedding_model": "extra-body-model", - "embedding_dimension": 768, - }, - ) - - with pytest.raises(ValueError, match="Embedding model inconsistent between metadata"): - await vector_io_adapter.openai_create_vector_store(params) - - # Reset mock for second test - vector_io_adapter.register_vector_db.reset_mock() - - # Test with inconsistent embedding dimension - params = OpenAICreateVectorStoreRequestWithExtraBody( - name="test_store", - metadata={ - "embedding_model": "same-model", - "embedding_dimension": "512", - }, - **{ - "embedding_model": "same-model", - "embedding_dimension": 1024, - }, - ) - - with pytest.raises(ValueError, match="Embedding dimension inconsistent between metadata"): - await vector_io_adapter.openai_create_vector_store(params) - - async def test_embedding_config_defaults_when_missing(vector_io_adapter): """Test that embedding dimension defaults to 768 when not provided.""" - # Mock register_vector_db to avoid actual registration - vector_io_adapter.register_vector_db = AsyncMock() + # Mock register_vector_store to avoid actual registration + vector_io_adapter.register_vector_store = AsyncMock() # Set provider_id attribute for the adapter vector_io_adapter.__provider_id__ = "test_provider" @@ -1234,8 +1099,8 @@ async def test_embedding_config_defaults_when_missing(vector_io_adapter): await vector_io_adapter.openai_create_vector_store(params) # Should default to 768 dimensions - vector_io_adapter.register_vector_db.assert_called_once() - call_args = vector_io_adapter.register_vector_db.call_args[0][0] + vector_io_adapter.register_vector_store.assert_called_once() + call_args = vector_io_adapter.register_vector_store.call_args[0][0] assert call_args.embedding_model == "model-without-dimension" assert call_args.embedding_dimension == 768 @@ -1243,8 +1108,8 @@ async def test_embedding_config_defaults_when_missing(vector_io_adapter): async def test_embedding_config_required_model_missing(vector_io_adapter): """Test that missing embedding model raises error.""" - # Mock register_vector_db to avoid actual registration - vector_io_adapter.register_vector_db = AsyncMock() + # Mock register_vector_store to avoid actual registration + vector_io_adapter.register_vector_store = AsyncMock() # Set provider_id attribute for the adapter vector_io_adapter.__provider_id__ = "test_provider" # Mock the default model lookup to return None (no default model available) @@ -1253,5 +1118,5 @@ async def test_embedding_config_required_model_missing(vector_io_adapter): # Test with no embedding model provided params = OpenAICreateVectorStoreRequestWithExtraBody(name="test_store", metadata={}) - with pytest.raises(ValueError, match="embedding_model is required in extra_body when creating a vector store"): + with pytest.raises(ValueError, match="embedding_model is required"): await vector_io_adapter.openai_create_vector_store(params) diff --git a/tests/unit/rag/test_rag_query.py b/tests/unit/rag/test_rag_query.py index a45b66f02..c012bc4f0 100644 --- a/tests/unit/rag/test_rag_query.py +++ b/tests/unit/rag/test_rag_query.py @@ -18,7 +18,7 @@ from llama_stack.providers.inline.tool_runtime.rag.memory import MemoryToolRunti class TestRagQuery: - async def test_query_raises_on_empty_vector_db_ids(self): + async def test_query_raises_on_empty_vector_store_ids(self): rag_tool = MemoryToolRuntimeImpl( config=MagicMock(), vector_io_api=MagicMock(), inference_api=MagicMock(), files_api=MagicMock() ) @@ -82,7 +82,7 @@ class TestRagQuery: with pytest.raises(ValueError): RAGQueryConfig(mode="wrong_mode") - async def test_query_adds_vector_db_id_to_chunk_metadata(self): + async def test_query_adds_vector_store_id_to_chunk_metadata(self): rag_tool = MemoryToolRuntimeImpl( config=MagicMock(), vector_io_api=MagicMock(), diff --git a/tests/unit/rag/test_vector_store.py b/tests/unit/rag/test_vector_store.py index 1e40c98e8..200da5c26 100644 --- a/tests/unit/rag/test_vector_store.py +++ b/tests/unit/rag/test_vector_store.py @@ -21,7 +21,7 @@ from llama_stack.apis.tools import RAGDocument from llama_stack.apis.vector_io import Chunk from llama_stack.providers.utils.memory.vector_store import ( URL, - VectorDBWithIndex, + VectorStoreWithIndex, _validate_embedding, content_from_doc, make_overlapped_chunks, @@ -206,15 +206,15 @@ class TestVectorStore: assert str(excinfo.value.__cause__) == "Cannot convert to string" -class TestVectorDBWithIndex: +class TestVectorStoreWithIndex: async def test_insert_chunks_without_embeddings(self): - mock_vector_db = MagicMock() - mock_vector_db.embedding_model = "test-model without embeddings" + mock_vector_store = MagicMock() + mock_vector_store.embedding_model = "test-model without embeddings" mock_index = AsyncMock() mock_inference_api = AsyncMock() - vector_db_with_index = VectorDBWithIndex( - vector_db=mock_vector_db, index=mock_index, inference_api=mock_inference_api + vector_store_with_index = VectorStoreWithIndex( + vector_store=mock_vector_store, index=mock_index, inference_api=mock_inference_api ) chunks = [ @@ -227,7 +227,7 @@ class TestVectorDBWithIndex: OpenAIEmbeddingData(embedding=[0.4, 0.5, 0.6], index=1), ] - await vector_db_with_index.insert_chunks(chunks) + await vector_store_with_index.insert_chunks(chunks) # Verify openai_embeddings was called with correct params mock_inference_api.openai_embeddings.assert_called_once() @@ -243,14 +243,14 @@ class TestVectorDBWithIndex: assert np.array_equal(args[1], np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]], dtype=np.float32)) async def test_insert_chunks_with_valid_embeddings(self): - mock_vector_db = MagicMock() - mock_vector_db.embedding_model = "test-model with embeddings" - mock_vector_db.embedding_dimension = 3 + mock_vector_store = MagicMock() + mock_vector_store.embedding_model = "test-model with embeddings" + mock_vector_store.embedding_dimension = 3 mock_index = AsyncMock() mock_inference_api = AsyncMock() - vector_db_with_index = VectorDBWithIndex( - vector_db=mock_vector_db, index=mock_index, inference_api=mock_inference_api + vector_store_with_index = VectorStoreWithIndex( + vector_store=mock_vector_store, index=mock_index, inference_api=mock_inference_api ) chunks = [ @@ -258,7 +258,7 @@ class TestVectorDBWithIndex: Chunk(content="Test 2", embedding=[0.4, 0.5, 0.6], metadata={}), ] - await vector_db_with_index.insert_chunks(chunks) + await vector_store_with_index.insert_chunks(chunks) mock_inference_api.openai_embeddings.assert_not_called() mock_index.add_chunks.assert_called_once() @@ -267,14 +267,14 @@ class TestVectorDBWithIndex: assert np.array_equal(args[1], np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]], dtype=np.float32)) async def test_insert_chunks_with_invalid_embeddings(self): - mock_vector_db = MagicMock() - mock_vector_db.embedding_dimension = 3 - mock_vector_db.embedding_model = "test-model with invalid embeddings" + mock_vector_store = MagicMock() + mock_vector_store.embedding_dimension = 3 + mock_vector_store.embedding_model = "test-model with invalid embeddings" mock_index = AsyncMock() mock_inference_api = AsyncMock() - vector_db_with_index = VectorDBWithIndex( - vector_db=mock_vector_db, index=mock_index, inference_api=mock_inference_api + vector_store_with_index = VectorStoreWithIndex( + vector_store=mock_vector_store, index=mock_index, inference_api=mock_inference_api ) # Verify Chunk raises ValueError for invalid embedding type @@ -283,7 +283,7 @@ class TestVectorDBWithIndex: # Verify Chunk raises ValueError for invalid embedding type in insert_chunks (i.e., Chunk errors before insert_chunks is called) with pytest.raises(ValueError, match="Input should be a valid list"): - await vector_db_with_index.insert_chunks( + await vector_store_with_index.insert_chunks( [ Chunk(content="Test 1", embedding=None, metadata={}), Chunk(content="Test 2", embedding="invalid_type", metadata={}), @@ -292,7 +292,7 @@ class TestVectorDBWithIndex: # Verify Chunk raises ValueError for invalid embedding element type in insert_chunks (i.e., Chunk errors before insert_chunks is called) with pytest.raises(ValueError, match=" Input should be a valid number, unable to parse string as a number "): - await vector_db_with_index.insert_chunks( + await vector_store_with_index.insert_chunks( Chunk(content="Test 1", embedding=[0.1, "string", 0.3], metadata={}) ) @@ -300,20 +300,20 @@ class TestVectorDBWithIndex: Chunk(content="Test 1", embedding=[0.1, 0.2, 0.3, 0.4], metadata={}), ] with pytest.raises(ValueError, match="has dimension 4, expected 3"): - await vector_db_with_index.insert_chunks(chunks_wrong_dim) + await vector_store_with_index.insert_chunks(chunks_wrong_dim) mock_inference_api.openai_embeddings.assert_not_called() mock_index.add_chunks.assert_not_called() async def test_insert_chunks_with_partially_precomputed_embeddings(self): - mock_vector_db = MagicMock() - mock_vector_db.embedding_model = "test-model with partial embeddings" - mock_vector_db.embedding_dimension = 3 + mock_vector_store = MagicMock() + mock_vector_store.embedding_model = "test-model with partial embeddings" + mock_vector_store.embedding_dimension = 3 mock_index = AsyncMock() mock_inference_api = AsyncMock() - vector_db_with_index = VectorDBWithIndex( - vector_db=mock_vector_db, index=mock_index, inference_api=mock_inference_api + vector_store_with_index = VectorStoreWithIndex( + vector_store=mock_vector_store, index=mock_index, inference_api=mock_inference_api ) chunks = [ @@ -327,7 +327,7 @@ class TestVectorDBWithIndex: OpenAIEmbeddingData(embedding=[0.3, 0.3, 0.3], index=1), ] - await vector_db_with_index.insert_chunks(chunks) + await vector_store_with_index.insert_chunks(chunks) # Verify openai_embeddings was called with correct params mock_inference_api.openai_embeddings.assert_called_once() diff --git a/tests/unit/registry/test_registry.py b/tests/unit/registry/test_registry.py index e49c9dc77..d4c9786d1 100644 --- a/tests/unit/registry/test_registry.py +++ b/tests/unit/registry/test_registry.py @@ -8,24 +8,24 @@ import pytest from llama_stack.apis.inference import Model -from llama_stack.apis.vector_dbs import VectorDB -from llama_stack.core.datatypes import VectorDBWithOwner +from llama_stack.apis.vector_stores import VectorStore +from llama_stack.core.datatypes import VectorStoreWithOwner +from llama_stack.core.storage.datatypes import KVStoreReference, SqliteKVStoreConfig from llama_stack.core.store.registry import ( KEY_FORMAT, CachedDiskDistributionRegistry, DiskDistributionRegistry, ) -from llama_stack.providers.utils.kvstore import kvstore_impl -from llama_stack.providers.utils.kvstore.config import SqliteKVStoreConfig +from llama_stack.providers.utils.kvstore import kvstore_impl, register_kvstore_backends @pytest.fixture -def sample_vector_db(): - return VectorDB( - identifier="test_vector_db", +def sample_vector_store(): + return VectorStore( + identifier="test_vector_store", embedding_model="nomic-embed-text-v1.5", embedding_dimension=768, - provider_resource_id="test_vector_db", + provider_resource_id="test_vector_store", provider_id="test-provider", ) @@ -45,17 +45,17 @@ async def test_registry_initialization(disk_dist_registry): assert result is None -async def test_basic_registration(disk_dist_registry, sample_vector_db, sample_model): - print(f"Registering {sample_vector_db}") - await disk_dist_registry.register(sample_vector_db) +async def test_basic_registration(disk_dist_registry, sample_vector_store, sample_model): + print(f"Registering {sample_vector_store}") + await disk_dist_registry.register(sample_vector_store) print(f"Registering {sample_model}") await disk_dist_registry.register(sample_model) - print("Getting vector_db") - result_vector_db = await disk_dist_registry.get("vector_db", "test_vector_db") - assert result_vector_db is not None - assert result_vector_db.identifier == sample_vector_db.identifier - assert result_vector_db.embedding_model == sample_vector_db.embedding_model - assert result_vector_db.provider_id == sample_vector_db.provider_id + print("Getting vector_store") + result_vector_store = await disk_dist_registry.get("vector_store", "test_vector_store") + assert result_vector_store is not None + assert result_vector_store.identifier == sample_vector_store.identifier + assert result_vector_store.embedding_model == sample_vector_store.embedding_model + assert result_vector_store.provider_id == sample_vector_store.provider_id result_model = await disk_dist_registry.get("model", "test_model") assert result_model is not None @@ -63,127 +63,137 @@ async def test_basic_registration(disk_dist_registry, sample_vector_db, sample_m assert result_model.provider_id == sample_model.provider_id -async def test_cached_registry_initialization(sqlite_kvstore, sample_vector_db, sample_model): +async def test_cached_registry_initialization(sqlite_kvstore, sample_vector_store, sample_model): # First populate the disk registry disk_registry = DiskDistributionRegistry(sqlite_kvstore) await disk_registry.initialize() - await disk_registry.register(sample_vector_db) + await disk_registry.register(sample_vector_store) await disk_registry.register(sample_model) # Test cached version loads from disk db_path = sqlite_kvstore.db_path - cached_registry = CachedDiskDistributionRegistry(await kvstore_impl(SqliteKVStoreConfig(db_path=db_path))) + backend_name = "kv_cached_test" + register_kvstore_backends({backend_name: SqliteKVStoreConfig(db_path=db_path)}) + cached_registry = CachedDiskDistributionRegistry( + await kvstore_impl(KVStoreReference(backend=backend_name, namespace="registry")) + ) await cached_registry.initialize() - result_vector_db = await cached_registry.get("vector_db", "test_vector_db") - assert result_vector_db is not None - assert result_vector_db.identifier == sample_vector_db.identifier - assert result_vector_db.embedding_model == sample_vector_db.embedding_model - assert result_vector_db.embedding_dimension == sample_vector_db.embedding_dimension - assert result_vector_db.provider_id == sample_vector_db.provider_id + result_vector_store = await cached_registry.get("vector_store", "test_vector_store") + assert result_vector_store is not None + assert result_vector_store.identifier == sample_vector_store.identifier + assert result_vector_store.embedding_model == sample_vector_store.embedding_model + assert result_vector_store.embedding_dimension == sample_vector_store.embedding_dimension + assert result_vector_store.provider_id == sample_vector_store.provider_id async def test_cached_registry_updates(cached_disk_dist_registry): - new_vector_db = VectorDB( - identifier="test_vector_db_2", + new_vector_store = VectorStore( + identifier="test_vector_store_2", embedding_model="nomic-embed-text-v1.5", embedding_dimension=768, - provider_resource_id="test_vector_db_2", + provider_resource_id="test_vector_store_2", provider_id="baz", ) - await cached_disk_dist_registry.register(new_vector_db) + await cached_disk_dist_registry.register(new_vector_store) # Verify in cache - result_vector_db = await cached_disk_dist_registry.get("vector_db", "test_vector_db_2") - assert result_vector_db is not None - assert result_vector_db.identifier == new_vector_db.identifier - assert result_vector_db.provider_id == new_vector_db.provider_id + result_vector_store = await cached_disk_dist_registry.get("vector_store", "test_vector_store_2") + assert result_vector_store is not None + assert result_vector_store.identifier == new_vector_store.identifier + assert result_vector_store.provider_id == new_vector_store.provider_id # Verify persisted to disk db_path = cached_disk_dist_registry.kvstore.db_path - new_registry = DiskDistributionRegistry(await kvstore_impl(SqliteKVStoreConfig(db_path=db_path))) + backend_name = "kv_cached_new" + register_kvstore_backends({backend_name: SqliteKVStoreConfig(db_path=db_path)}) + new_registry = DiskDistributionRegistry( + await kvstore_impl(KVStoreReference(backend=backend_name, namespace="registry")) + ) await new_registry.initialize() - result_vector_db = await new_registry.get("vector_db", "test_vector_db_2") - assert result_vector_db is not None - assert result_vector_db.identifier == new_vector_db.identifier - assert result_vector_db.provider_id == new_vector_db.provider_id + result_vector_store = await new_registry.get("vector_store", "test_vector_store_2") + assert result_vector_store is not None + assert result_vector_store.identifier == new_vector_store.identifier + assert result_vector_store.provider_id == new_vector_store.provider_id async def test_duplicate_provider_registration(cached_disk_dist_registry): - original_vector_db = VectorDB( - identifier="test_vector_db_2", + original_vector_store = VectorStore( + identifier="test_vector_store_2", embedding_model="nomic-embed-text-v1.5", embedding_dimension=768, - provider_resource_id="test_vector_db_2", + provider_resource_id="test_vector_store_2", provider_id="baz", ) - assert await cached_disk_dist_registry.register(original_vector_db) + assert await cached_disk_dist_registry.register(original_vector_store) - duplicate_vector_db = VectorDB( - identifier="test_vector_db_2", + duplicate_vector_store = VectorStore( + identifier="test_vector_store_2", embedding_model="different-model", embedding_dimension=768, - provider_resource_id="test_vector_db_2", + provider_resource_id="test_vector_store_2", provider_id="baz", # Same provider_id ) - with pytest.raises(ValueError, match="Object of type 'vector_db' and identifier 'test_vector_db_2' already exists"): - await cached_disk_dist_registry.register(duplicate_vector_db) + with pytest.raises( + ValueError, match="Object of type 'vector_store' and identifier 'test_vector_store_2' already exists" + ): + await cached_disk_dist_registry.register(duplicate_vector_store) - result = await cached_disk_dist_registry.get("vector_db", "test_vector_db_2") + result = await cached_disk_dist_registry.get("vector_store", "test_vector_store_2") assert result is not None - assert result.embedding_model == original_vector_db.embedding_model # Original values preserved + assert result.embedding_model == original_vector_store.embedding_model # Original values preserved async def test_get_all_objects(cached_disk_dist_registry): # Create multiple test banks # Create multiple test banks - test_vector_dbs = [ - VectorDB( - identifier=f"test_vector_db_{i}", + test_vector_stores = [ + VectorStore( + identifier=f"test_vector_store_{i}", embedding_model="nomic-embed-text-v1.5", embedding_dimension=768, - provider_resource_id=f"test_vector_db_{i}", + provider_resource_id=f"test_vector_store_{i}", provider_id=f"provider_{i}", ) for i in range(3) ] - # Register all vector_dbs - for vector_db in test_vector_dbs: - await cached_disk_dist_registry.register(vector_db) + # Register all vector_stores + for vector_store in test_vector_stores: + await cached_disk_dist_registry.register(vector_store) # Test get_all retrieval all_results = await cached_disk_dist_registry.get_all() assert len(all_results) == 3 - # Verify each vector_db was stored correctly - for original_vector_db in test_vector_dbs: - matching_vector_dbs = [v for v in all_results if v.identifier == original_vector_db.identifier] - assert len(matching_vector_dbs) == 1 - stored_vector_db = matching_vector_dbs[0] - assert stored_vector_db.embedding_model == original_vector_db.embedding_model - assert stored_vector_db.provider_id == original_vector_db.provider_id - assert stored_vector_db.embedding_dimension == original_vector_db.embedding_dimension + # Verify each vector_store was stored correctly + for original_vector_store in test_vector_stores: + matching_vector_stores = [v for v in all_results if v.identifier == original_vector_store.identifier] + assert len(matching_vector_stores) == 1 + stored_vector_store = matching_vector_stores[0] + assert stored_vector_store.embedding_model == original_vector_store.embedding_model + assert stored_vector_store.provider_id == original_vector_store.provider_id + assert stored_vector_store.embedding_dimension == original_vector_store.embedding_dimension async def test_parse_registry_values_error_handling(sqlite_kvstore): - valid_db = VectorDB( - identifier="valid_vector_db", + valid_db = VectorStore( + identifier="valid_vector_store", embedding_model="nomic-embed-text-v1.5", embedding_dimension=768, - provider_resource_id="valid_vector_db", + provider_resource_id="valid_vector_store", provider_id="test-provider", ) await sqlite_kvstore.set( - KEY_FORMAT.format(type="vector_db", identifier="valid_vector_db"), valid_db.model_dump_json() + KEY_FORMAT.format(type="vector_store", identifier="valid_vector_store"), valid_db.model_dump_json() ) - await sqlite_kvstore.set(KEY_FORMAT.format(type="vector_db", identifier="corrupted_json"), "{not valid json") + await sqlite_kvstore.set(KEY_FORMAT.format(type="vector_store", identifier="corrupted_json"), "{not valid json") await sqlite_kvstore.set( - KEY_FORMAT.format(type="vector_db", identifier="missing_fields"), - '{"type": "vector_db", "identifier": "missing_fields"}', + KEY_FORMAT.format(type="vector_store", identifier="missing_fields"), + '{"type": "vector_store", "identifier": "missing_fields"}', ) test_registry = DiskDistributionRegistry(sqlite_kvstore) @@ -194,18 +204,18 @@ async def test_parse_registry_values_error_handling(sqlite_kvstore): # Should have filtered out the invalid entries assert len(all_objects) == 1 - assert all_objects[0].identifier == "valid_vector_db" + assert all_objects[0].identifier == "valid_vector_store" # Check that the get method also handles errors correctly - invalid_obj = await test_registry.get("vector_db", "corrupted_json") + invalid_obj = await test_registry.get("vector_store", "corrupted_json") assert invalid_obj is None - invalid_obj = await test_registry.get("vector_db", "missing_fields") + invalid_obj = await test_registry.get("vector_store", "missing_fields") assert invalid_obj is None async def test_cached_registry_error_handling(sqlite_kvstore): - valid_db = VectorDB( + valid_db = VectorStore( identifier="valid_cached_db", embedding_model="nomic-embed-text-v1.5", embedding_dimension=768, @@ -214,12 +224,12 @@ async def test_cached_registry_error_handling(sqlite_kvstore): ) await sqlite_kvstore.set( - KEY_FORMAT.format(type="vector_db", identifier="valid_cached_db"), valid_db.model_dump_json() + KEY_FORMAT.format(type="vector_store", identifier="valid_cached_db"), valid_db.model_dump_json() ) await sqlite_kvstore.set( - KEY_FORMAT.format(type="vector_db", identifier="invalid_cached_db"), - '{"type": "vector_db", "identifier": "invalid_cached_db", "embedding_model": 12345}', # Should be string + KEY_FORMAT.format(type="vector_store", identifier="invalid_cached_db"), + '{"type": "vector_store", "identifier": "invalid_cached_db", "embedding_model": 12345}', # Should be string ) cached_registry = CachedDiskDistributionRegistry(sqlite_kvstore) @@ -229,63 +239,65 @@ async def test_cached_registry_error_handling(sqlite_kvstore): assert len(all_objects) == 1 assert all_objects[0].identifier == "valid_cached_db" - invalid_obj = await cached_registry.get("vector_db", "invalid_cached_db") + invalid_obj = await cached_registry.get("vector_store", "invalid_cached_db") assert invalid_obj is None async def test_double_registration_identical_objects(disk_dist_registry): """Test that registering identical objects succeeds (idempotent).""" - vector_db = VectorDBWithOwner( - identifier="test_vector_db", + vector_store = VectorStoreWithOwner( + identifier="test_vector_store", embedding_model="all-MiniLM-L6-v2", embedding_dimension=384, - provider_resource_id="test_vector_db", + provider_resource_id="test_vector_store", provider_id="test-provider", ) # First registration should succeed - result1 = await disk_dist_registry.register(vector_db) + result1 = await disk_dist_registry.register(vector_store) assert result1 is True # Second registration of identical object should also succeed (idempotent) - result2 = await disk_dist_registry.register(vector_db) + result2 = await disk_dist_registry.register(vector_store) assert result2 is True # Verify object exists and is unchanged - retrieved = await disk_dist_registry.get("vector_db", "test_vector_db") + retrieved = await disk_dist_registry.get("vector_store", "test_vector_store") assert retrieved is not None - assert retrieved.identifier == vector_db.identifier - assert retrieved.embedding_model == vector_db.embedding_model + assert retrieved.identifier == vector_store.identifier + assert retrieved.embedding_model == vector_store.embedding_model async def test_double_registration_different_objects(disk_dist_registry): """Test that registering different objects with same identifier fails.""" - vector_db1 = VectorDBWithOwner( - identifier="test_vector_db", + vector_store1 = VectorStoreWithOwner( + identifier="test_vector_store", embedding_model="all-MiniLM-L6-v2", embedding_dimension=384, - provider_resource_id="test_vector_db", + provider_resource_id="test_vector_store", provider_id="test-provider", ) - vector_db2 = VectorDBWithOwner( - identifier="test_vector_db", # Same identifier + vector_store2 = VectorStoreWithOwner( + identifier="test_vector_store", # Same identifier embedding_model="different-model", # Different embedding model embedding_dimension=384, - provider_resource_id="test_vector_db", + provider_resource_id="test_vector_store", provider_id="test-provider", ) # First registration should succeed - result1 = await disk_dist_registry.register(vector_db1) + result1 = await disk_dist_registry.register(vector_store1) assert result1 is True # Second registration with different data should fail - with pytest.raises(ValueError, match="Object of type 'vector_db' and identifier 'test_vector_db' already exists"): - await disk_dist_registry.register(vector_db2) + with pytest.raises( + ValueError, match="Object of type 'vector_store' and identifier 'test_vector_store' already exists" + ): + await disk_dist_registry.register(vector_store2) # Verify original object is unchanged - retrieved = await disk_dist_registry.get("vector_db", "test_vector_db") + retrieved = await disk_dist_registry.get("vector_store", "test_vector_store") assert retrieved is not None assert retrieved.embedding_model == "all-MiniLM-L6-v2" # Original value diff --git a/tests/unit/server/test_auth.py b/tests/unit/server/test_auth.py index 04ae89db8..75cbf518b 100644 --- a/tests/unit/server/test_auth.py +++ b/tests/unit/server/test_auth.py @@ -516,6 +516,82 @@ def test_get_attributes_from_claims(): assert set(attributes["teams"]) == {"my-team", "group1", "group2"} assert attributes["namespaces"] == ["my-tenant"] + # Test nested claims with dot notation (e.g., Keycloak resource_access structure) + claims = { + "sub": "user123", + "resource_access": {"llamastack": {"roles": ["inference_max", "admin"]}, "other-client": {"roles": ["viewer"]}}, + "realm_access": {"roles": ["offline_access", "uma_authorization"]}, + } + attributes = get_attributes_from_claims( + claims, {"resource_access.llamastack.roles": "roles", "realm_access.roles": "realm_roles"} + ) + assert set(attributes["roles"]) == {"inference_max", "admin"} + assert set(attributes["realm_roles"]) == {"offline_access", "uma_authorization"} + + # Test that dot notation takes precedence over literal keys with dots + claims = { + "my.dotted.key": "literal-value", + "my": {"dotted": {"key": "nested-value"}}, + } + attributes = get_attributes_from_claims(claims, {"my.dotted.key": "test"}) + assert attributes["test"] == ["nested-value"] + + # Test that literal key works when nested traversal doesn't exist + claims = { + "my.dotted.key": "literal-value", + } + attributes = get_attributes_from_claims(claims, {"my.dotted.key": "test"}) + assert attributes["test"] == ["literal-value"] + + # Test missing nested paths are handled gracefully + claims = { + "sub": "user123", + "resource_access": {"other-client": {"roles": ["viewer"]}}, + } + attributes = get_attributes_from_claims( + claims, + { + "resource_access.llamastack.roles": "roles", # Missing nested path + "resource_access.missing.key": "missing_attr", # Missing nested path + "completely.missing.path": "another_missing", # Completely missing + "sub": "username", # Existing path + }, + ) + # Only the existing claim should be in attributes + assert attributes["username"] == ["user123"] + assert "roles" not in attributes + assert "missing_attr" not in attributes + assert "another_missing" not in attributes + + # Test mixture of flat and nested claims paths + claims = { + "sub": "user456", + "flat_key": "flat-value", + "scope": "read write admin", + "resource_access": {"app1": {"roles": ["role1", "role2"]}, "app2": {"roles": ["role3"]}}, + "groups": ["group1", "group2"], + "metadata": {"tenant": "tenant1", "region": "us-west"}, + } + attributes = get_attributes_from_claims( + claims, + { + "sub": "user_id", # Flat string + "scope": "permissions", # Flat string with spaces + "groups": "teams", # Flat list + "resource_access.app1.roles": "app1_roles", # Nested list + "resource_access.app2.roles": "app2_roles", # Nested list + "metadata.tenant": "tenant", # Nested string + "metadata.region": "region", # Nested string + }, + ) + assert attributes["user_id"] == ["user456"] + assert set(attributes["permissions"]) == {"read", "write", "admin"} + assert set(attributes["teams"]) == {"group1", "group2"} + assert set(attributes["app1_roles"]) == {"role1", "role2"} + assert attributes["app2_roles"] == ["role3"] + assert attributes["tenant"] == ["tenant1"] + assert attributes["region"] == ["us-west"] + # TODO: add more tests for oauth2 token provider diff --git a/tests/unit/server/test_quota.py b/tests/unit/server/test_quota.py index 85acbc66a..16b1772ce 100644 --- a/tests/unit/server/test_quota.py +++ b/tests/unit/server/test_quota.py @@ -4,6 +4,8 @@ # This source code is licensed under the terms described in the LICENSE file in # the root directory of this source tree. +from uuid import uuid4 + import pytest from fastapi import FastAPI, Request from fastapi.testclient import TestClient @@ -11,7 +13,8 @@ from starlette.middleware.base import BaseHTTPMiddleware from llama_stack.core.datatypes import QuotaConfig, QuotaPeriod from llama_stack.core.server.quota import QuotaMiddleware -from llama_stack.providers.utils.kvstore.config import SqliteKVStoreConfig +from llama_stack.core.storage.datatypes import KVStoreReference, SqliteKVStoreConfig +from llama_stack.providers.utils.kvstore import register_kvstore_backends class InjectClientIDMiddleware(BaseHTTPMiddleware): @@ -29,8 +32,10 @@ class InjectClientIDMiddleware(BaseHTTPMiddleware): def build_quota_config(db_path) -> QuotaConfig: + backend_name = f"kv_quota_{uuid4().hex}" + register_kvstore_backends({backend_name: SqliteKVStoreConfig(db_path=str(db_path))}) return QuotaConfig( - kvstore=SqliteKVStoreConfig(db_path=str(db_path)), + kvstore=KVStoreReference(backend=backend_name, namespace="quota"), anonymous_max_requests=1, authenticated_max_requests=2, period=QuotaPeriod.DAY, diff --git a/tests/unit/server/test_resolver.py b/tests/unit/server/test_resolver.py index 1ee1b2f47..b44f12f7e 100644 --- a/tests/unit/server/test_resolver.py +++ b/tests/unit/server/test_resolver.py @@ -12,15 +12,22 @@ from unittest.mock import AsyncMock, MagicMock from pydantic import BaseModel, Field from llama_stack.apis.inference import Inference -from llama_stack.core.datatypes import ( - Api, - Provider, - StackRunConfig, -) +from llama_stack.core.datatypes import Api, Provider, StackRunConfig from llama_stack.core.resolver import resolve_impls from llama_stack.core.routers.inference import InferenceRouter from llama_stack.core.routing_tables.models import ModelsRoutingTable +from llama_stack.core.storage.datatypes import ( + InferenceStoreReference, + KVStoreReference, + ServerStoresConfig, + SqliteKVStoreConfig, + SqliteSqlStoreConfig, + SqlStoreReference, + StorageConfig, +) from llama_stack.providers.datatypes import InlineProviderSpec, ProviderSpec +from llama_stack.providers.utils.kvstore import register_kvstore_backends +from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends def add_protocol_methods(cls: type, protocol: type[Protocol]) -> None: @@ -65,6 +72,35 @@ class SampleImpl: pass +def make_run_config(**overrides) -> StackRunConfig: + storage = overrides.pop( + "storage", + StorageConfig( + backends={ + "kv_default": SqliteKVStoreConfig(db_path=":memory:"), + "sql_default": SqliteSqlStoreConfig(db_path=":memory:"), + }, + stores=ServerStoresConfig( + metadata=KVStoreReference(backend="kv_default", namespace="registry"), + inference=InferenceStoreReference(backend="sql_default", table_name="inference_store"), + conversations=SqlStoreReference(backend="sql_default", table_name="conversations"), + ), + ), + ) + register_kvstore_backends({name: cfg for name, cfg in storage.backends.items() if cfg.type.value.startswith("kv_")}) + register_sqlstore_backends( + {name: cfg for name, cfg in storage.backends.items() if cfg.type.value.startswith("sql_")} + ) + defaults = dict( + image_name="test_image", + apis=[], + providers={}, + storage=storage, + ) + defaults.update(overrides) + return StackRunConfig(**defaults) + + async def test_resolve_impls_basic(): # Create a real provider spec provider_spec = InlineProviderSpec( @@ -78,7 +114,7 @@ async def test_resolve_impls_basic(): # Create provider registry with our provider provider_registry = {Api.inference: {provider_spec.provider_type: provider_spec}} - run_config = StackRunConfig( + run_config = make_run_config( image_name="test_image", providers={ "inference": [ diff --git a/tests/unit/server/test_server.py b/tests/unit/server/test_server.py index f21bbdd67..d6d4f4f23 100644 --- a/tests/unit/server/test_server.py +++ b/tests/unit/server/test_server.py @@ -41,7 +41,7 @@ class TestTranslateException: self.identifier = identifier self.owner = owner - resource = MockResource("vector_db", "test-db") + resource = MockResource("vector_store", "test-db") exc = AccessDeniedError("create", resource, user) result = translate_exception(exc) @@ -49,7 +49,7 @@ class TestTranslateException: assert isinstance(result, HTTPException) assert result.status_code == 403 assert "test-user" in result.detail - assert "vector_db::test-db" in result.detail + assert "vector_store::test-db" in result.detail assert "create" in result.detail assert "roles=['user']" in result.detail assert "teams=['dev']" in result.detail diff --git a/tests/unit/utils/inference/test_inference_store.py b/tests/unit/utils/inference/test_inference_store.py index f6d63490a..d2de1c759 100644 --- a/tests/unit/utils/inference/test_inference_store.py +++ b/tests/unit/utils/inference/test_inference_store.py @@ -5,7 +5,6 @@ # the root directory of this source tree. import time -from tempfile import TemporaryDirectory import pytest @@ -16,8 +15,16 @@ from llama_stack.apis.inference import ( OpenAIUserMessageParam, Order, ) +from llama_stack.core.storage.datatypes import InferenceStoreReference, SqliteSqlStoreConfig from llama_stack.providers.utils.inference.inference_store import InferenceStore -from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig +from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends + + +@pytest.fixture(autouse=True) +def setup_backends(tmp_path): + """Register SQL store backends for testing.""" + db_path = str(tmp_path / "test.db") + register_sqlstore_backends({"sql_default": SqliteSqlStoreConfig(db_path=db_path)}) def create_test_chat_completion( @@ -44,167 +51,162 @@ def create_test_chat_completion( async def test_inference_store_pagination_basic(): """Test basic pagination functionality.""" - with TemporaryDirectory() as tmp_dir: - db_path = tmp_dir + "/test.db" - store = InferenceStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) - await store.initialize() + reference = InferenceStoreReference(backend="sql_default", table_name="chat_completions") + store = InferenceStore(reference, policy=[]) + await store.initialize() - # Create test data with different timestamps - base_time = int(time.time()) - test_data = [ - ("zebra-task", base_time + 1), - ("apple-job", base_time + 2), - ("moon-work", base_time + 3), - ("banana-run", base_time + 4), - ("car-exec", base_time + 5), - ] + # Create test data with different timestamps + base_time = int(time.time()) + test_data = [ + ("zebra-task", base_time + 1), + ("apple-job", base_time + 2), + ("moon-work", base_time + 3), + ("banana-run", base_time + 4), + ("car-exec", base_time + 5), + ] - # Store test chat completions - for completion_id, timestamp in test_data: - completion = create_test_chat_completion(completion_id, timestamp) - input_messages = [OpenAIUserMessageParam(role="user", content=f"Test message for {completion_id}")] - await store.store_chat_completion(completion, input_messages) + # Store test chat completions + for completion_id, timestamp in test_data: + completion = create_test_chat_completion(completion_id, timestamp) + input_messages = [OpenAIUserMessageParam(role="user", content=f"Test message for {completion_id}")] + await store.store_chat_completion(completion, input_messages) - # Wait for all queued writes to complete - await store.flush() + # Wait for all queued writes to complete + await store.flush() - # Test 1: First page with limit=2, descending order (default) - result = await store.list_chat_completions(limit=2, order=Order.desc) - assert len(result.data) == 2 - assert result.data[0].id == "car-exec" # Most recent first - assert result.data[1].id == "banana-run" - assert result.has_more is True - assert result.last_id == "banana-run" + # Test 1: First page with limit=2, descending order (default) + result = await store.list_chat_completions(limit=2, order=Order.desc) + assert len(result.data) == 2 + assert result.data[0].id == "car-exec" # Most recent first + assert result.data[1].id == "banana-run" + assert result.has_more is True + assert result.last_id == "banana-run" - # Test 2: Second page using 'after' parameter - result2 = await store.list_chat_completions(after="banana-run", limit=2, order=Order.desc) - assert len(result2.data) == 2 - assert result2.data[0].id == "moon-work" - assert result2.data[1].id == "apple-job" - assert result2.has_more is True + # Test 2: Second page using 'after' parameter + result2 = await store.list_chat_completions(after="banana-run", limit=2, order=Order.desc) + assert len(result2.data) == 2 + assert result2.data[0].id == "moon-work" + assert result2.data[1].id == "apple-job" + assert result2.has_more is True - # Test 3: Final page - result3 = await store.list_chat_completions(after="apple-job", limit=2, order=Order.desc) - assert len(result3.data) == 1 - assert result3.data[0].id == "zebra-task" - assert result3.has_more is False + # Test 3: Final page + result3 = await store.list_chat_completions(after="apple-job", limit=2, order=Order.desc) + assert len(result3.data) == 1 + assert result3.data[0].id == "zebra-task" + assert result3.has_more is False async def test_inference_store_pagination_ascending(): """Test pagination with ascending order.""" - with TemporaryDirectory() as tmp_dir: - db_path = tmp_dir + "/test.db" - store = InferenceStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) - await store.initialize() + reference = InferenceStoreReference(backend="sql_default", table_name="chat_completions") + store = InferenceStore(reference, policy=[]) + await store.initialize() - # Create test data - base_time = int(time.time()) - test_data = [ - ("delta-item", base_time + 1), - ("charlie-task", base_time + 2), - ("alpha-work", base_time + 3), - ] + # Create test data + base_time = int(time.time()) + test_data = [ + ("delta-item", base_time + 1), + ("charlie-task", base_time + 2), + ("alpha-work", base_time + 3), + ] - # Store test chat completions - for completion_id, timestamp in test_data: - completion = create_test_chat_completion(completion_id, timestamp) - input_messages = [OpenAIUserMessageParam(role="user", content=f"Test message for {completion_id}")] - await store.store_chat_completion(completion, input_messages) + # Store test chat completions + for completion_id, timestamp in test_data: + completion = create_test_chat_completion(completion_id, timestamp) + input_messages = [OpenAIUserMessageParam(role="user", content=f"Test message for {completion_id}")] + await store.store_chat_completion(completion, input_messages) - # Wait for all queued writes to complete - await store.flush() + # Wait for all queued writes to complete + await store.flush() - # Test ascending order pagination - result = await store.list_chat_completions(limit=1, order=Order.asc) - assert len(result.data) == 1 - assert result.data[0].id == "delta-item" # Oldest first - assert result.has_more is True + # Test ascending order pagination + result = await store.list_chat_completions(limit=1, order=Order.asc) + assert len(result.data) == 1 + assert result.data[0].id == "delta-item" # Oldest first + assert result.has_more is True - # Second page with ascending order - result2 = await store.list_chat_completions(after="delta-item", limit=1, order=Order.asc) - assert len(result2.data) == 1 - assert result2.data[0].id == "charlie-task" - assert result2.has_more is True + # Second page with ascending order + result2 = await store.list_chat_completions(after="delta-item", limit=1, order=Order.asc) + assert len(result2.data) == 1 + assert result2.data[0].id == "charlie-task" + assert result2.has_more is True async def test_inference_store_pagination_with_model_filter(): """Test pagination combined with model filtering.""" - with TemporaryDirectory() as tmp_dir: - db_path = tmp_dir + "/test.db" - store = InferenceStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) - await store.initialize() + reference = InferenceStoreReference(backend="sql_default", table_name="chat_completions") + store = InferenceStore(reference, policy=[]) + await store.initialize() - # Create test data with different models - base_time = int(time.time()) - test_data = [ - ("xyz-task", base_time + 1, "model-a"), - ("def-work", base_time + 2, "model-b"), - ("pqr-job", base_time + 3, "model-a"), - ("abc-run", base_time + 4, "model-b"), - ] + # Create test data with different models + base_time = int(time.time()) + test_data = [ + ("xyz-task", base_time + 1, "model-a"), + ("def-work", base_time + 2, "model-b"), + ("pqr-job", base_time + 3, "model-a"), + ("abc-run", base_time + 4, "model-b"), + ] - # Store test chat completions - for completion_id, timestamp, model in test_data: - completion = create_test_chat_completion(completion_id, timestamp, model) - input_messages = [OpenAIUserMessageParam(role="user", content=f"Test message for {completion_id}")] - await store.store_chat_completion(completion, input_messages) + # Store test chat completions + for completion_id, timestamp, model in test_data: + completion = create_test_chat_completion(completion_id, timestamp, model) + input_messages = [OpenAIUserMessageParam(role="user", content=f"Test message for {completion_id}")] + await store.store_chat_completion(completion, input_messages) - # Wait for all queued writes to complete - await store.flush() + # Wait for all queued writes to complete + await store.flush() - # Test pagination with model filter - result = await store.list_chat_completions(limit=1, model="model-a", order=Order.desc) - assert len(result.data) == 1 - assert result.data[0].id == "pqr-job" # Most recent model-a - assert result.data[0].model == "model-a" - assert result.has_more is True + # Test pagination with model filter + result = await store.list_chat_completions(limit=1, model="model-a", order=Order.desc) + assert len(result.data) == 1 + assert result.data[0].id == "pqr-job" # Most recent model-a + assert result.data[0].model == "model-a" + assert result.has_more is True - # Second page with model filter - result2 = await store.list_chat_completions(after="pqr-job", limit=1, model="model-a", order=Order.desc) - assert len(result2.data) == 1 - assert result2.data[0].id == "xyz-task" - assert result2.data[0].model == "model-a" - assert result2.has_more is False + # Second page with model filter + result2 = await store.list_chat_completions(after="pqr-job", limit=1, model="model-a", order=Order.desc) + assert len(result2.data) == 1 + assert result2.data[0].id == "xyz-task" + assert result2.data[0].model == "model-a" + assert result2.has_more is False async def test_inference_store_pagination_invalid_after(): """Test error handling for invalid 'after' parameter.""" - with TemporaryDirectory() as tmp_dir: - db_path = tmp_dir + "/test.db" - store = InferenceStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) - await store.initialize() + reference = InferenceStoreReference(backend="sql_default", table_name="chat_completions") + store = InferenceStore(reference, policy=[]) + await store.initialize() - # Try to paginate with non-existent ID - with pytest.raises(ValueError, match="Record with id='non-existent' not found in table 'chat_completions'"): - await store.list_chat_completions(after="non-existent", limit=2) + # Try to paginate with non-existent ID + with pytest.raises(ValueError, match="Record with id='non-existent' not found in table 'chat_completions'"): + await store.list_chat_completions(after="non-existent", limit=2) async def test_inference_store_pagination_no_limit(): """Test pagination behavior when no limit is specified.""" - with TemporaryDirectory() as tmp_dir: - db_path = tmp_dir + "/test.db" - store = InferenceStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) - await store.initialize() + reference = InferenceStoreReference(backend="sql_default", table_name="chat_completions") + store = InferenceStore(reference, policy=[]) + await store.initialize() - # Create test data - base_time = int(time.time()) - test_data = [ - ("omega-first", base_time + 1), - ("beta-second", base_time + 2), - ] + # Create test data + base_time = int(time.time()) + test_data = [ + ("omega-first", base_time + 1), + ("beta-second", base_time + 2), + ] - # Store test chat completions - for completion_id, timestamp in test_data: - completion = create_test_chat_completion(completion_id, timestamp) - input_messages = [OpenAIUserMessageParam(role="user", content=f"Test message for {completion_id}")] - await store.store_chat_completion(completion, input_messages) + # Store test chat completions + for completion_id, timestamp in test_data: + completion = create_test_chat_completion(completion_id, timestamp) + input_messages = [OpenAIUserMessageParam(role="user", content=f"Test message for {completion_id}")] + await store.store_chat_completion(completion, input_messages) - # Wait for all queued writes to complete - await store.flush() + # Wait for all queued writes to complete + await store.flush() - # Test without limit - result = await store.list_chat_completions(order=Order.desc) - assert len(result.data) == 2 - assert result.data[0].id == "beta-second" # Most recent first - assert result.data[1].id == "omega-first" - assert result.has_more is False + # Test without limit + result = await store.list_chat_completions(order=Order.desc) + assert len(result.data) == 2 + assert result.data[0].id == "beta-second" # Most recent first + assert result.data[1].id == "omega-first" + assert result.has_more is False diff --git a/tests/unit/utils/responses/test_responses_store.py b/tests/unit/utils/responses/test_responses_store.py index c27b5a8e5..34cff3d3f 100644 --- a/tests/unit/utils/responses/test_responses_store.py +++ b/tests/unit/utils/responses/test_responses_store.py @@ -6,6 +6,7 @@ import time from tempfile import TemporaryDirectory +from uuid import uuid4 import pytest @@ -15,8 +16,18 @@ from llama_stack.apis.agents.openai_responses import ( OpenAIResponseObject, ) from llama_stack.apis.inference import OpenAIMessageParam, OpenAIUserMessageParam +from llama_stack.core.storage.datatypes import ResponsesStoreReference, SqliteSqlStoreConfig from llama_stack.providers.utils.responses.responses_store import ResponsesStore -from llama_stack.providers.utils.sqlstore.sqlstore import SqliteSqlStoreConfig +from llama_stack.providers.utils.sqlstore.sqlstore import register_sqlstore_backends + + +def build_store(db_path: str, policy: list | None = None) -> ResponsesStore: + backend_name = f"sql_responses_{uuid4().hex}" + register_sqlstore_backends({backend_name: SqliteSqlStoreConfig(db_path=db_path)}) + return ResponsesStore( + ResponsesStoreReference(backend=backend_name, table_name="responses"), + policy=policy or [], + ) def create_test_response_object( @@ -54,7 +65,7 @@ async def test_responses_store_pagination_basic(): """Test basic pagination functionality for responses store.""" with TemporaryDirectory() as tmp_dir: db_path = tmp_dir + "/test.db" - store = ResponsesStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) + store = build_store(db_path) await store.initialize() # Create test data with different timestamps @@ -103,7 +114,7 @@ async def test_responses_store_pagination_ascending(): """Test pagination with ascending order.""" with TemporaryDirectory() as tmp_dir: db_path = tmp_dir + "/test.db" - store = ResponsesStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) + store = build_store(db_path) await store.initialize() # Create test data @@ -141,7 +152,7 @@ async def test_responses_store_pagination_with_model_filter(): """Test pagination combined with model filtering.""" with TemporaryDirectory() as tmp_dir: db_path = tmp_dir + "/test.db" - store = ResponsesStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) + store = build_store(db_path) await store.initialize() # Create test data with different models @@ -182,7 +193,7 @@ async def test_responses_store_pagination_invalid_after(): """Test error handling for invalid 'after' parameter.""" with TemporaryDirectory() as tmp_dir: db_path = tmp_dir + "/test.db" - store = ResponsesStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) + store = build_store(db_path) await store.initialize() # Try to paginate with non-existent ID @@ -194,7 +205,7 @@ async def test_responses_store_pagination_no_limit(): """Test pagination behavior when no limit is specified.""" with TemporaryDirectory() as tmp_dir: db_path = tmp_dir + "/test.db" - store = ResponsesStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) + store = build_store(db_path) await store.initialize() # Create test data @@ -226,7 +237,7 @@ async def test_responses_store_get_response_object(): """Test retrieving a single response object.""" with TemporaryDirectory() as tmp_dir: db_path = tmp_dir + "/test.db" - store = ResponsesStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) + store = build_store(db_path) await store.initialize() # Store a test response @@ -254,7 +265,7 @@ async def test_responses_store_input_items_pagination(): """Test pagination functionality for input items.""" with TemporaryDirectory() as tmp_dir: db_path = tmp_dir + "/test.db" - store = ResponsesStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) + store = build_store(db_path) await store.initialize() # Store a test response with many inputs with explicit IDs @@ -335,7 +346,7 @@ async def test_responses_store_input_items_before_pagination(): """Test before pagination functionality for input items.""" with TemporaryDirectory() as tmp_dir: db_path = tmp_dir + "/test.db" - store = ResponsesStore(SqliteSqlStoreConfig(db_path=db_path), policy=[]) + store = build_store(db_path) await store.initialize() # Store a test response with many inputs with explicit IDs diff --git a/uv.lock b/uv.lock index f9806123d..82c6a3ae6 100644 --- a/uv.lock +++ b/uv.lock @@ -921,16 +921,16 @@ wheels = [ [[package]] name = "fastapi" -version = "0.116.1" +version = "0.119.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/d7/6c8b3bfe33eeffa208183ec037fee0cce9f7f024089ab1c5d12ef04bd27c/fastapi-0.116.1.tar.gz", hash = "sha256:ed52cbf946abfd70c5a0dccb24673f0670deeb517a88b3544d03c2a6bf283143", size = 296485, upload-time = "2025-07-11T16:22:32.057Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/f9/5c5bcce82a7997cc0eb8c47b7800f862f6b56adc40486ed246e5010d443b/fastapi-0.119.0.tar.gz", hash = "sha256:451082403a2c1f0b99c6bd57c09110ed5463856804c8078d38e5a1f1035dbbb7", size = 336756, upload-time = "2025-10-11T17:13:40.53Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/47/d63c60f59a59467fda0f93f46335c9d18526d7071f025cb5b89d5353ea42/fastapi-0.116.1-py3-none-any.whl", hash = "sha256:c46ac7c312df840f0c9e220f7964bada936781bc4e2e6eb71f1c4d7553786565", size = 95631, upload-time = "2025-07-11T16:22:30.485Z" }, + { url = "https://files.pythonhosted.org/packages/ce/70/584c4d7cad80f5e833715c0a29962d7c93b4d18eed522a02981a6d1b6ee5/fastapi-0.119.0-py3-none-any.whl", hash = "sha256:90a2e49ed19515320abb864df570dd766be0662c5d577688f1600170f7f73cf2", size = 107095, upload-time = "2025-10-11T17:13:39.048Z" }, ] [[package]] @@ -1756,7 +1756,7 @@ wheels = [ [[package]] name = "llama-stack" -version = "0.2.23" +version = "0.3.0" source = { editable = "." } dependencies = [ { name = "aiohttp" }, @@ -1889,8 +1889,8 @@ requires-dist = [ { name = "httpx" }, { name = "jinja2", specifier = ">=3.1.6" }, { name = "jsonschema" }, - { name = "llama-stack-client", specifier = ">=0.2.23" }, - { name = "llama-stack-client", marker = "extra == 'ui'", specifier = ">=0.2.23" }, + { name = "llama-stack-client", specifier = ">=0.3.0" }, + { name = "llama-stack-client", marker = "extra == 'ui'", specifier = ">=0.3.0" }, { name = "openai", specifier = ">=1.107" }, { name = "opentelemetry-exporter-otlp-proto-http", specifier = ">=1.30.0" }, { name = "opentelemetry-sdk", specifier = ">=1.30.0" }, @@ -1996,7 +1996,7 @@ unit = [ [[package]] name = "llama-stack-client" -version = "0.2.23" +version = "0.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, @@ -2015,9 +2015,9 @@ dependencies = [ { name = "tqdm" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/8f/306d5fcf2f97b3a6251219b03c194836a2ff4e0fcc8146c9970e50a72cd3/llama_stack_client-0.2.23.tar.gz", hash = "sha256:68f34e8ac8eea6a73ed9d4977d849992b2d8bd835804d770a11843431cd5bf74", size = 322288, upload-time = "2025-09-26T21:11:08.342Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/d9/3c720f420fc80ce51de1a0ad90c53edc613617b68980137dcf716a86198a/llama_stack_client-0.3.0.tar.gz", hash = "sha256:1e974a74d0da285e18ba7df30b9a324e250782b130253bcef3e695830c5bb03d", size = 340443, upload-time = "2025-10-21T23:58:25.855Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/75/3eb58e092a681804013dbec7b7f549d18f55acf6fd6e6b27de7e249766d8/llama_stack_client-0.2.23-py3-none-any.whl", hash = "sha256:eee42c74eee8f218f9455e5a06d5d4be43f8a8c82a7937ef51ce367f916df847", size = 379809, upload-time = "2025-09-26T21:11:06.856Z" }, + { url = "https://files.pythonhosted.org/packages/96/27/1c65035ce58100be22409c98e4d65b1cdaeff7811ea968f9f844641330d7/llama_stack_client-0.3.0-py3-none-any.whl", hash = "sha256:9f85d84d508ef7da44b96ca8555d7783da717cfc9135bab6a5530fe8c852690d", size = 425234, upload-time = "2025-10-21T23:58:24.246Z" }, ] [[package]] @@ -4129,27 +4129,28 @@ wheels = [ [[package]] name = "ruff" -version = "0.9.10" +version = "0.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/20/8e/fafaa6f15c332e73425d9c44ada85360501045d5ab0b81400076aff27cf6/ruff-0.9.10.tar.gz", hash = "sha256:9bacb735d7bada9cfb0f2c227d3658fc443d90a727b47f206fb33f52f3c0eac7", size = 3759776, upload-time = "2025-03-07T15:27:44.363Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/58/6ca66896635352812de66f71cdf9ff86b3a4f79071ca5730088c0cd0fc8d/ruff-0.14.1.tar.gz", hash = "sha256:1dd86253060c4772867c61791588627320abcb6ed1577a90ef432ee319729b69", size = 5513429, upload-time = "2025-10-16T18:05:41.766Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/73/b2/af7c2cc9e438cbc19fafeec4f20bfcd72165460fe75b2b6e9a0958c8c62b/ruff-0.9.10-py3-none-linux_armv6l.whl", hash = "sha256:eb4d25532cfd9fe461acc83498361ec2e2252795b4f40b17e80692814329e42d", size = 10049494, upload-time = "2025-03-07T15:26:51.268Z" }, - { url = "https://files.pythonhosted.org/packages/6d/12/03f6dfa1b95ddd47e6969f0225d60d9d7437c91938a310835feb27927ca0/ruff-0.9.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:188a6638dab1aa9bb6228a7302387b2c9954e455fb25d6b4470cb0641d16759d", size = 10853584, upload-time = "2025-03-07T15:26:56.104Z" }, - { url = "https://files.pythonhosted.org/packages/02/49/1c79e0906b6ff551fb0894168763f705bf980864739572b2815ecd3c9df0/ruff-0.9.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5284dcac6b9dbc2fcb71fdfc26a217b2ca4ede6ccd57476f52a587451ebe450d", size = 10155692, upload-time = "2025-03-07T15:27:01.385Z" }, - { url = "https://files.pythonhosted.org/packages/5b/01/85e8082e41585e0e1ceb11e41c054e9e36fed45f4b210991052d8a75089f/ruff-0.9.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47678f39fa2a3da62724851107f438c8229a3470f533894b5568a39b40029c0c", size = 10369760, upload-time = "2025-03-07T15:27:04.023Z" }, - { url = "https://files.pythonhosted.org/packages/a1/90/0bc60bd4e5db051f12445046d0c85cc2c617095c0904f1aa81067dc64aea/ruff-0.9.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:99713a6e2766b7a17147b309e8c915b32b07a25c9efd12ada79f217c9c778b3e", size = 9912196, upload-time = "2025-03-07T15:27:06.93Z" }, - { url = "https://files.pythonhosted.org/packages/66/ea/0b7e8c42b1ec608033c4d5a02939c82097ddcb0b3e393e4238584b7054ab/ruff-0.9.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524ee184d92f7c7304aa568e2db20f50c32d1d0caa235d8ddf10497566ea1a12", size = 11434985, upload-time = "2025-03-07T15:27:10.082Z" }, - { url = "https://files.pythonhosted.org/packages/d5/86/3171d1eff893db4f91755175a6e1163c5887be1f1e2f4f6c0c59527c2bfd/ruff-0.9.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:df92aeac30af821f9acf819fc01b4afc3dfb829d2782884f8739fb52a8119a16", size = 12155842, upload-time = "2025-03-07T15:27:12.727Z" }, - { url = "https://files.pythonhosted.org/packages/89/9e/700ca289f172a38eb0bca752056d0a42637fa17b81649b9331786cb791d7/ruff-0.9.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de42e4edc296f520bb84954eb992a07a0ec5a02fecb834498415908469854a52", size = 11613804, upload-time = "2025-03-07T15:27:15.944Z" }, - { url = "https://files.pythonhosted.org/packages/f2/92/648020b3b5db180f41a931a68b1c8575cca3e63cec86fd26807422a0dbad/ruff-0.9.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d257f95b65806104b6b1ffca0ea53f4ef98454036df65b1eda3693534813ecd1", size = 13823776, upload-time = "2025-03-07T15:27:18.996Z" }, - { url = "https://files.pythonhosted.org/packages/5e/a6/cc472161cd04d30a09d5c90698696b70c169eeba2c41030344194242db45/ruff-0.9.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b60dec7201c0b10d6d11be00e8f2dbb6f40ef1828ee75ed739923799513db24c", size = 11302673, upload-time = "2025-03-07T15:27:21.655Z" }, - { url = "https://files.pythonhosted.org/packages/6c/db/d31c361c4025b1b9102b4d032c70a69adb9ee6fde093f6c3bf29f831c85c/ruff-0.9.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d838b60007da7a39c046fcdd317293d10b845001f38bcb55ba766c3875b01e43", size = 10235358, upload-time = "2025-03-07T15:27:24.72Z" }, - { url = "https://files.pythonhosted.org/packages/d1/86/d6374e24a14d4d93ebe120f45edd82ad7dcf3ef999ffc92b197d81cdc2a5/ruff-0.9.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ccaf903108b899beb8e09a63ffae5869057ab649c1e9231c05ae354ebc62066c", size = 9886177, upload-time = "2025-03-07T15:27:27.282Z" }, - { url = "https://files.pythonhosted.org/packages/00/62/a61691f6eaaac1e945a1f3f59f1eea9a218513139d5b6c2b8f88b43b5b8f/ruff-0.9.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f9567d135265d46e59d62dc60c0bfad10e9a6822e231f5b24032dba5a55be6b5", size = 10864747, upload-time = "2025-03-07T15:27:30.637Z" }, - { url = "https://files.pythonhosted.org/packages/ee/94/2c7065e1d92a8a8a46d46d9c3cf07b0aa7e0a1e0153d74baa5e6620b4102/ruff-0.9.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5f202f0d93738c28a89f8ed9eaba01b7be339e5d8d642c994347eaa81c6d75b8", size = 11360441, upload-time = "2025-03-07T15:27:33.356Z" }, - { url = "https://files.pythonhosted.org/packages/a7/8f/1f545ea6f9fcd7bf4368551fb91d2064d8f0577b3079bb3f0ae5779fb773/ruff-0.9.10-py3-none-win32.whl", hash = "sha256:bfb834e87c916521ce46b1788fbb8484966e5113c02df216680102e9eb960029", size = 10247401, upload-time = "2025-03-07T15:27:35.994Z" }, - { url = "https://files.pythonhosted.org/packages/4f/18/fb703603ab108e5c165f52f5b86ee2aa9be43bb781703ec87c66a5f5d604/ruff-0.9.10-py3-none-win_amd64.whl", hash = "sha256:f2160eeef3031bf4b17df74e307d4c5fb689a6f3a26a2de3f7ef4044e3c484f1", size = 11366360, upload-time = "2025-03-07T15:27:38.66Z" }, - { url = "https://files.pythonhosted.org/packages/35/85/338e603dc68e7d9994d5d84f24adbf69bae760ba5efd3e20f5ff2cec18da/ruff-0.9.10-py3-none-win_arm64.whl", hash = "sha256:5fd804c0327a5e5ea26615550e706942f348b197d5475ff34c19733aee4b2e69", size = 10436892, upload-time = "2025-03-07T15:27:41.687Z" }, + { url = "https://files.pythonhosted.org/packages/8d/39/9cc5ab181478d7a18adc1c1e051a84ee02bec94eb9bdfd35643d7c74ca31/ruff-0.14.1-py3-none-linux_armv6l.whl", hash = "sha256:083bfc1f30f4a391ae09c6f4f99d83074416b471775b59288956f5bc18e82f8b", size = 12445415, upload-time = "2025-10-16T18:04:48.227Z" }, + { url = "https://files.pythonhosted.org/packages/ef/2e/1226961855ccd697255988f5a2474890ac7c5863b080b15bd038df820818/ruff-0.14.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:f6fa757cd717f791009f7669fefb09121cc5f7d9bd0ef211371fad68c2b8b224", size = 12784267, upload-time = "2025-10-16T18:04:52.515Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ea/fd9e95863124ed159cd0667ec98449ae461de94acda7101f1acb6066da00/ruff-0.14.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d6191903d39ac156921398e9c86b7354d15e3c93772e7dbf26c9fcae59ceccd5", size = 11781872, upload-time = "2025-10-16T18:04:55.396Z" }, + { url = "https://files.pythonhosted.org/packages/1e/5a/e890f7338ff537dba4589a5e02c51baa63020acfb7c8cbbaea4831562c96/ruff-0.14.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed04f0e04f7a4587244e5c9d7df50e6b5bf2705d75059f409a6421c593a35896", size = 12226558, upload-time = "2025-10-16T18:04:58.166Z" }, + { url = "https://files.pythonhosted.org/packages/a6/7a/8ab5c3377f5bf31e167b73651841217542bcc7aa1c19e83030835cc25204/ruff-0.14.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5c9e6cf6cd4acae0febbce29497accd3632fe2025c0c583c8b87e8dbdeae5f61", size = 12187898, upload-time = "2025-10-16T18:05:01.455Z" }, + { url = "https://files.pythonhosted.org/packages/48/8d/ba7c33aa55406955fc124e62c8259791c3d42e3075a71710fdff9375134f/ruff-0.14.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fa2458527794ecdfbe45f654e42c61f2503a230545a91af839653a0a93dbc6", size = 12939168, upload-time = "2025-10-16T18:05:04.397Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c2/70783f612b50f66d083380e68cbd1696739d88e9b4f6164230375532c637/ruff-0.14.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:39f1c392244e338b21d42ab29b8a6392a722c5090032eb49bb4d6defcdb34345", size = 14386942, upload-time = "2025-10-16T18:05:07.102Z" }, + { url = "https://files.pythonhosted.org/packages/48/44/cd7abb9c776b66d332119d67f96acf15830d120f5b884598a36d9d3f4d83/ruff-0.14.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7382fa12a26cce1f95070ce450946bec357727aaa428983036362579eadcc5cf", size = 13990622, upload-time = "2025-10-16T18:05:09.882Z" }, + { url = "https://files.pythonhosted.org/packages/eb/56/4259b696db12ac152fe472764b4f78bbdd9b477afd9bc3a6d53c01300b37/ruff-0.14.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd0bf2be3ae8521e1093a487c4aa3b455882f139787770698530d28ed3fbb37c", size = 13431143, upload-time = "2025-10-16T18:05:13.46Z" }, + { url = "https://files.pythonhosted.org/packages/e0/35/266a80d0eb97bd224b3265b9437bd89dde0dcf4faf299db1212e81824e7e/ruff-0.14.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabcaa9ccf8089fb4fdb78d17cc0e28241520f50f4c2e88cb6261ed083d85151", size = 13132844, upload-time = "2025-10-16T18:05:16.1Z" }, + { url = "https://files.pythonhosted.org/packages/65/6e/d31ce218acc11a8d91ef208e002a31acf315061a85132f94f3df7a252b18/ruff-0.14.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:747d583400f6125ec11a4c14d1c8474bf75d8b419ad22a111a537ec1a952d192", size = 13401241, upload-time = "2025-10-16T18:05:19.395Z" }, + { url = "https://files.pythonhosted.org/packages/9f/b5/dbc4221bf0b03774b3b2f0d47f39e848d30664157c15b965a14d890637d2/ruff-0.14.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5a6e74c0efd78515a1d13acbfe6c90f0f5bd822aa56b4a6d43a9ffb2ae6e56cd", size = 12132476, upload-time = "2025-10-16T18:05:22.163Z" }, + { url = "https://files.pythonhosted.org/packages/98/4b/ac99194e790ccd092d6a8b5f341f34b6e597d698e3077c032c502d75ea84/ruff-0.14.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0ea6a864d2fb41a4b6d5b456ed164302a0d96f4daac630aeba829abfb059d020", size = 12139749, upload-time = "2025-10-16T18:05:25.162Z" }, + { url = "https://files.pythonhosted.org/packages/47/26/7df917462c3bb5004e6fdfcc505a49e90bcd8a34c54a051953118c00b53a/ruff-0.14.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0826b8764f94229604fa255918d1cc45e583e38c21c203248b0bfc9a0e930be5", size = 12544758, upload-time = "2025-10-16T18:05:28.018Z" }, + { url = "https://files.pythonhosted.org/packages/64/d0/81e7f0648e9764ad9b51dd4be5e5dac3fcfff9602428ccbae288a39c2c22/ruff-0.14.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:cbc52160465913a1a3f424c81c62ac8096b6a491468e7d872cb9444a860bc33d", size = 13221811, upload-time = "2025-10-16T18:05:30.707Z" }, + { url = "https://files.pythonhosted.org/packages/c3/07/3c45562c67933cc35f6d5df4ca77dabbcd88fddaca0d6b8371693d29fd56/ruff-0.14.1-py3-none-win32.whl", hash = "sha256:e037ea374aaaff4103240ae79168c0945ae3d5ae8db190603de3b4012bd1def6", size = 12319467, upload-time = "2025-10-16T18:05:33.261Z" }, + { url = "https://files.pythonhosted.org/packages/02/88/0ee4ca507d4aa05f67e292d2e5eb0b3e358fbcfe527554a2eda9ac422d6b/ruff-0.14.1-py3-none-win_amd64.whl", hash = "sha256:59d599cdff9c7f925a017f6f2c256c908b094e55967f93f2821b1439928746a1", size = 13401123, upload-time = "2025-10-16T18:05:35.984Z" }, + { url = "https://files.pythonhosted.org/packages/b8/81/4b6387be7014858d924b843530e1b2a8e531846807516e9bea2ee0936bf7/ruff-0.14.1-py3-none-win_arm64.whl", hash = "sha256:e3b443c4c9f16ae850906b8d0a707b2a4c16f8d2f0a7fe65c475c5886665ce44", size = 12436636, upload-time = "2025-10-16T18:05:38.995Z" }, ] [[package]] @@ -4525,31 +4526,31 @@ wheels = [ [[package]] name = "sqlalchemy" -version = "2.0.41" +version = "2.0.44" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" }, + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/63/66/45b165c595ec89aa7dcc2c1cd222ab269bc753f1fc7a1e68f8481bd957bf/sqlalchemy-2.0.41.tar.gz", hash = "sha256:edba70118c4be3c2b1f90754d308d0b79c6fe2c0fdc52d8ddf603916f83f4db9", size = 9689424, upload-time = "2025-05-14T17:10:32.339Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/f2/840d7b9496825333f532d2e3976b8eadbf52034178aac53630d09fe6e1ef/sqlalchemy-2.0.44.tar.gz", hash = "sha256:0ae7454e1ab1d780aee69fd2aae7d6b8670a581d8847f2d1e0f7ddfbf47e5a22", size = 9819830, upload-time = "2025-10-10T14:39:12.935Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/2a/f1f4e068b371154740dd10fb81afb5240d5af4aa0087b88d8b308b5429c2/sqlalchemy-2.0.41-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:81f413674d85cfd0dfcd6512e10e0f33c19c21860342a4890c3a2b59479929f9", size = 2119645, upload-time = "2025-05-14T17:55:24.854Z" }, - { url = "https://files.pythonhosted.org/packages/9b/e8/c664a7e73d36fbfc4730f8cf2bf930444ea87270f2825efbe17bf808b998/sqlalchemy-2.0.41-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:598d9ebc1e796431bbd068e41e4de4dc34312b7aa3292571bb3674a0cb415dd1", size = 2107399, upload-time = "2025-05-14T17:55:28.097Z" }, - { url = "https://files.pythonhosted.org/packages/5c/78/8a9cf6c5e7135540cb682128d091d6afa1b9e48bd049b0d691bf54114f70/sqlalchemy-2.0.41-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a104c5694dfd2d864a6f91b0956eb5d5883234119cb40010115fd45a16da5e70", size = 3293269, upload-time = "2025-05-14T17:50:38.227Z" }, - { url = "https://files.pythonhosted.org/packages/3c/35/f74add3978c20de6323fb11cb5162702670cc7a9420033befb43d8d5b7a4/sqlalchemy-2.0.41-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6145afea51ff0af7f2564a05fa95eb46f542919e6523729663a5d285ecb3cf5e", size = 3303364, upload-time = "2025-05-14T17:51:49.829Z" }, - { url = "https://files.pythonhosted.org/packages/6a/d4/c990f37f52c3f7748ebe98883e2a0f7d038108c2c5a82468d1ff3eec50b7/sqlalchemy-2.0.41-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b46fa6eae1cd1c20e6e6f44e19984d438b6b2d8616d21d783d150df714f44078", size = 3229072, upload-time = "2025-05-14T17:50:39.774Z" }, - { url = "https://files.pythonhosted.org/packages/15/69/cab11fecc7eb64bc561011be2bd03d065b762d87add52a4ca0aca2e12904/sqlalchemy-2.0.41-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41836fe661cc98abfae476e14ba1906220f92c4e528771a8a3ae6a151242d2ae", size = 3268074, upload-time = "2025-05-14T17:51:51.736Z" }, - { url = "https://files.pythonhosted.org/packages/5c/ca/0c19ec16858585d37767b167fc9602593f98998a68a798450558239fb04a/sqlalchemy-2.0.41-cp312-cp312-win32.whl", hash = "sha256:a8808d5cf866c781150d36a3c8eb3adccfa41a8105d031bf27e92c251e3969d6", size = 2084514, upload-time = "2025-05-14T17:55:49.915Z" }, - { url = "https://files.pythonhosted.org/packages/7f/23/4c2833d78ff3010a4e17f984c734f52b531a8c9060a50429c9d4b0211be6/sqlalchemy-2.0.41-cp312-cp312-win_amd64.whl", hash = "sha256:5b14e97886199c1f52c14629c11d90c11fbb09e9334fa7bb5f6d068d9ced0ce0", size = 2111557, upload-time = "2025-05-14T17:55:51.349Z" }, - { url = "https://files.pythonhosted.org/packages/d3/ad/2e1c6d4f235a97eeef52d0200d8ddda16f6c4dd70ae5ad88c46963440480/sqlalchemy-2.0.41-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4eeb195cdedaf17aab6b247894ff2734dcead6c08f748e617bfe05bd5a218443", size = 2115491, upload-time = "2025-05-14T17:55:31.177Z" }, - { url = "https://files.pythonhosted.org/packages/cf/8d/be490e5db8400dacc89056f78a52d44b04fbf75e8439569d5b879623a53b/sqlalchemy-2.0.41-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d4ae769b9c1c7757e4ccce94b0641bc203bbdf43ba7a2413ab2523d8d047d8dc", size = 2102827, upload-time = "2025-05-14T17:55:34.921Z" }, - { url = "https://files.pythonhosted.org/packages/a0/72/c97ad430f0b0e78efaf2791342e13ffeafcbb3c06242f01a3bb8fe44f65d/sqlalchemy-2.0.41-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a62448526dd9ed3e3beedc93df9bb6b55a436ed1474db31a2af13b313a70a7e1", size = 3225224, upload-time = "2025-05-14T17:50:41.418Z" }, - { url = "https://files.pythonhosted.org/packages/5e/51/5ba9ea3246ea068630acf35a6ba0d181e99f1af1afd17e159eac7e8bc2b8/sqlalchemy-2.0.41-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc56c9788617b8964ad02e8fcfeed4001c1f8ba91a9e1f31483c0dffb207002a", size = 3230045, upload-time = "2025-05-14T17:51:54.722Z" }, - { url = "https://files.pythonhosted.org/packages/78/2f/8c14443b2acea700c62f9b4a8bad9e49fc1b65cfb260edead71fd38e9f19/sqlalchemy-2.0.41-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c153265408d18de4cc5ded1941dcd8315894572cddd3c58df5d5b5705b3fa28d", size = 3159357, upload-time = "2025-05-14T17:50:43.483Z" }, - { url = "https://files.pythonhosted.org/packages/fc/b2/43eacbf6ccc5276d76cea18cb7c3d73e294d6fb21f9ff8b4eef9b42bbfd5/sqlalchemy-2.0.41-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f67766965996e63bb46cfbf2ce5355fc32d9dd3b8ad7e536a920ff9ee422e23", size = 3197511, upload-time = "2025-05-14T17:51:57.308Z" }, - { url = "https://files.pythonhosted.org/packages/fa/2e/677c17c5d6a004c3c45334ab1dbe7b7deb834430b282b8a0f75ae220c8eb/sqlalchemy-2.0.41-cp313-cp313-win32.whl", hash = "sha256:bfc9064f6658a3d1cadeaa0ba07570b83ce6801a1314985bf98ec9b95d74e15f", size = 2082420, upload-time = "2025-05-14T17:55:52.69Z" }, - { url = "https://files.pythonhosted.org/packages/e9/61/e8c1b9b6307c57157d328dd8b8348ddc4c47ffdf1279365a13b2b98b8049/sqlalchemy-2.0.41-cp313-cp313-win_amd64.whl", hash = "sha256:82ca366a844eb551daff9d2e6e7a9e5e76d2612c8564f58db6c19a726869c1df", size = 2108329, upload-time = "2025-05-14T17:55:54.495Z" }, - { url = "https://files.pythonhosted.org/packages/1c/fc/9ba22f01b5cdacc8f5ed0d22304718d2c758fce3fd49a5372b886a86f37c/sqlalchemy-2.0.41-py3-none-any.whl", hash = "sha256:57df5dc6fdb5ed1a88a1ed2195fd31927e705cad62dedd86b46972752a80f576", size = 1911224, upload-time = "2025-05-14T17:39:42.154Z" }, + { url = "https://files.pythonhosted.org/packages/62/c4/59c7c9b068e6813c898b771204aad36683c96318ed12d4233e1b18762164/sqlalchemy-2.0.44-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:72fea91746b5890f9e5e0997f16cbf3d53550580d76355ba2d998311b17b2250", size = 2139675, upload-time = "2025-10-10T16:03:31.064Z" }, + { url = "https://files.pythonhosted.org/packages/d6/ae/eeb0920537a6f9c5a3708e4a5fc55af25900216bdb4847ec29cfddf3bf3a/sqlalchemy-2.0.44-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:585c0c852a891450edbb1eaca8648408a3cc125f18cf433941fa6babcc359e29", size = 2127726, upload-time = "2025-10-10T16:03:35.934Z" }, + { url = "https://files.pythonhosted.org/packages/d8/d5/2ebbabe0379418eda8041c06b0b551f213576bfe4c2f09d77c06c07c8cc5/sqlalchemy-2.0.44-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b94843a102efa9ac68a7a30cd46df3ff1ed9c658100d30a725d10d9c60a2f44", size = 3327603, upload-time = "2025-10-10T15:35:28.322Z" }, + { url = "https://files.pythonhosted.org/packages/45/e5/5aa65852dadc24b7d8ae75b7efb8d19303ed6ac93482e60c44a585930ea5/sqlalchemy-2.0.44-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:119dc41e7a7defcefc57189cfa0e61b1bf9c228211aba432b53fb71ef367fda1", size = 3337842, upload-time = "2025-10-10T15:43:45.431Z" }, + { url = "https://files.pythonhosted.org/packages/41/92/648f1afd3f20b71e880ca797a960f638d39d243e233a7082c93093c22378/sqlalchemy-2.0.44-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0765e318ee9179b3718c4fd7ba35c434f4dd20332fbc6857a5e8df17719c24d7", size = 3264558, upload-time = "2025-10-10T15:35:29.93Z" }, + { url = "https://files.pythonhosted.org/packages/40/cf/e27d7ee61a10f74b17740918e23cbc5bc62011b48282170dc4c66da8ec0f/sqlalchemy-2.0.44-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2e7b5b079055e02d06a4308d0481658e4f06bc7ef211567edc8f7d5dce52018d", size = 3301570, upload-time = "2025-10-10T15:43:48.407Z" }, + { url = "https://files.pythonhosted.org/packages/3b/3d/3116a9a7b63e780fb402799b6da227435be878b6846b192f076d2f838654/sqlalchemy-2.0.44-cp312-cp312-win32.whl", hash = "sha256:846541e58b9a81cce7dee8329f352c318de25aa2f2bbe1e31587eb1f057448b4", size = 2103447, upload-time = "2025-10-10T15:03:21.678Z" }, + { url = "https://files.pythonhosted.org/packages/25/83/24690e9dfc241e6ab062df82cc0df7f4231c79ba98b273fa496fb3dd78ed/sqlalchemy-2.0.44-cp312-cp312-win_amd64.whl", hash = "sha256:7cbcb47fd66ab294703e1644f78971f6f2f1126424d2b300678f419aa73c7b6e", size = 2130912, upload-time = "2025-10-10T15:03:24.656Z" }, + { url = "https://files.pythonhosted.org/packages/45/d3/c67077a2249fdb455246e6853166360054c331db4613cda3e31ab1cadbef/sqlalchemy-2.0.44-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ff486e183d151e51b1d694c7aa1695747599bb00b9f5f604092b54b74c64a8e1", size = 2135479, upload-time = "2025-10-10T16:03:37.671Z" }, + { url = "https://files.pythonhosted.org/packages/2b/91/eabd0688330d6fd114f5f12c4f89b0d02929f525e6bf7ff80aa17ca802af/sqlalchemy-2.0.44-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1af8392eb27b372ddb783b317dea0f650241cea5bd29199b22235299ca2e45", size = 2123212, upload-time = "2025-10-10T16:03:41.755Z" }, + { url = "https://files.pythonhosted.org/packages/b0/bb/43e246cfe0e81c018076a16036d9b548c4cc649de241fa27d8d9ca6f85ab/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b61188657e3a2b9ac4e8f04d6cf8e51046e28175f79464c67f2fd35bceb0976", size = 3255353, upload-time = "2025-10-10T15:35:31.221Z" }, + { url = "https://files.pythonhosted.org/packages/b9/96/c6105ed9a880abe346b64d3b6ddef269ddfcab04f7f3d90a0bf3c5a88e82/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b87e7b91a5d5973dda5f00cd61ef72ad75a1db73a386b62877d4875a8840959c", size = 3260222, upload-time = "2025-10-10T15:43:50.124Z" }, + { url = "https://files.pythonhosted.org/packages/44/16/1857e35a47155b5ad927272fee81ae49d398959cb749edca6eaa399b582f/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15f3326f7f0b2bfe406ee562e17f43f36e16167af99c4c0df61db668de20002d", size = 3189614, upload-time = "2025-10-10T15:35:32.578Z" }, + { url = "https://files.pythonhosted.org/packages/88/ee/4afb39a8ee4fc786e2d716c20ab87b5b1fb33d4ac4129a1aaa574ae8a585/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e77faf6ff919aa8cd63f1c4e561cac1d9a454a191bb864d5dd5e545935e5a40", size = 3226248, upload-time = "2025-10-10T15:43:51.862Z" }, + { url = "https://files.pythonhosted.org/packages/32/d5/0e66097fc64fa266f29a7963296b40a80d6a997b7ac13806183700676f86/sqlalchemy-2.0.44-cp313-cp313-win32.whl", hash = "sha256:ee51625c2d51f8baadf2829fae817ad0b66b140573939dd69284d2ba3553ae73", size = 2101275, upload-time = "2025-10-10T15:03:26.096Z" }, + { url = "https://files.pythonhosted.org/packages/03/51/665617fe4f8c6450f42a6d8d69243f9420f5677395572c2fe9d21b493b7b/sqlalchemy-2.0.44-cp313-cp313-win_amd64.whl", hash = "sha256:c1c80faaee1a6c3428cecf40d16a2365bcf56c424c92c2b6f0f9ad204b899e9e", size = 2127901, upload-time = "2025-10-10T15:03:27.548Z" }, + { url = "https://files.pythonhosted.org/packages/9c/5e/6a29fa884d9fb7ddadf6b69490a9d45fded3b38541713010dad16b77d015/sqlalchemy-2.0.44-py3-none-any.whl", hash = "sha256:19de7ca1246fbef9f9d1bff8f1ab25641569df226364a0e40457dc5457c54b05", size = 1928718, upload-time = "2025-10-10T15:29:45.32Z" }, ] [package.optional-dependencies] @@ -5230,7 +5231,7 @@ wheels = [ [[package]] name = "weaviate-client" -version = "4.16.9" +version = "4.17.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "authlib" }, @@ -5241,9 +5242,9 @@ dependencies = [ { name = "pydantic" }, { name = "validators" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f4/e4/6a0b1501645f17a851067fc7bd0d5b53dc9777f2818be9c43debe06eda19/weaviate_client-4.16.9.tar.gz", hash = "sha256:d461071f1ff5ebddd0fc697959628a1d8caa12af1da071401ef25583c3084eba", size = 766390, upload-time = "2025-08-20T15:00:03.924Z" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/0e/e4582b007427187a9fde55fa575db4b766c81929d2b43a3dd8becce50567/weaviate_client-4.17.0.tar.gz", hash = "sha256:731d58d84b0989df4db399b686357ed285fb95971a492ccca8dec90bb2343c51", size = 769019, upload-time = "2025-09-26T11:20:27.381Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/1a/fc66f5f33961351c759d56453d18176849da8f64186c941183bb574b808b/weaviate_client-4.16.9-py3-none-any.whl", hash = "sha256:8b4adabaec0d513edef94c8c1de61c89a86eba3b63a4dc1acdfc9580e80199f4", size = 579098, upload-time = "2025-08-20T15:00:01.882Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c5/2da3a45866da7a935dab8ad07be05dcaee48b3ad4955144583b651929be7/weaviate_client-4.17.0-py3-none-any.whl", hash = "sha256:60e4a355b90537ee1e942ab0b76a94750897a13d9cf13c5a6decbd166d0ca8b5", size = 582763, upload-time = "2025-09-26T11:20:25.864Z" }, ] [[package]]