package main

import (
	"encoding/json"
	"testing"

	"github.com/higress-group/proxy-wasm-go-sdk/proxywasm/types"
	"github.com/higress-group/wasm-go/pkg/test"
	"github.com/stretchr/testify/require"
)

// 测试配置：完整配置
var completeConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"returnResponseTemplate": `{"id":"error","choices":[{"index":0,"message":{"role":"assistant","content":"%s"},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}}`,
		"llm": map[string]interface{}{
			"apiKey":           "test-api-key",
			"serviceName":      "llm-service",
			"servicePort":      8080,
			"domain":           "llm.example.com",
			"path":             "/v1/chat/completions",
			"model":            "qwen-turbo",
			"maxIterations":    20,
			"maxExecutionTime": 60000,
			"maxTokens":        2000,
		},
		"apis": []map[string]interface{}{
			{
				"apiProvider": map[string]interface{}{
					"serviceName":      "api-service",
					"servicePort":      9090,
					"domain":           "api.example.com",
					"maxExecutionTime": 30000,
					"apiKey": map[string]interface{}{
						"in":    "header",
						"name":  "Authorization",
						"value": "Bearer test-token",
					},
				},
				"api": `openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
servers:
  - url: https://api.example.com
paths:
  /weather:
    get:
      operationId: getWeather
      summary: Get weather information
      description: Retrieve current weather data
      parameters:
        - name: city
          in: query
          required: true
          schema:
            type: string
        - name: date
          in: query
          required: false
          schema:
            type: string
  /translate:
    post:
      operationId: translateText
      summary: Translate text
      description: Translate text to target language
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - text
                - targetLang
              properties:
                text:
                  type: string
                sourceLang:
                  type: string
                targetLang:
                  type: string`,
			},
		},
		"promptTemplate": map[string]interface{}{
			"language": "EN",
			"enTemplate": map[string]interface{}{
				"question":    "What is your question?",
				"thought1":    "Let me think about this",
				"observation": "Based on the observation",
				"thought2":    "Now I understand",
			},
			"chTemplate": map[string]interface{}{
				"question":    "你的问题是什么？",
				"thought1":    "让我思考一下",
				"observation": "基于观察结果",
				"thought2":    "现在我明白了",
			},
		},
		"jsonResp": map[string]interface{}{
			"enable": true,
			"jsonSchema": map[string]interface{}{
				"type": "object",
				"properties": map[string]interface{}{
					"answer": map[string]interface{}{
						"type": "string",
					},
				},
			},
		},
	})
	return data
}()

// 测试配置：最小配置（使用默认值）
var minimalConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"llm": map[string]interface{}{
			"apiKey":      "test-api-key",
			"serviceName": "llm-service",
			"servicePort": 8080,
			"domain":      "llm.example.com",
			"path":        "/v1/chat/completions",
			"model":       "qwen-turbo",
		},
		"apis": []map[string]interface{}{
			{
				"apiProvider": map[string]interface{}{
					"serviceName": "api-service",
					"servicePort": 9090,
					"domain":      "api.example.com",
					"apiKey": map[string]interface{}{
						"in":    "query",
						"name":  "api_key",
						"value": "test-token",
					},
				},
				"api": `openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
servers:
  - url: https://api.example.com
paths:
  /simple:
    get:
      operationId: simpleGet
      summary: Simple GET endpoint
      parameters:
        - name: id
          in: query
          required: true
          schema:
            type: string`,
			},
		},
	})
	return data
}()

// 测试配置：中文提示模板
var chinesePromptConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"llm": map[string]interface{}{
			"apiKey":      "test-api-key",
			"serviceName": "llm-service",
			"servicePort": 8080,
			"domain":      "llm.example.com",
			"path":        "/v1/chat/completions",
			"model":       "qwen-turbo",
		},
		"apis": []map[string]interface{}{
			{
				"apiProvider": map[string]interface{}{
					"serviceName": "api-service",
					"servicePort": 9090,
					"domain":      "api.example.com",
					"apiKey": map[string]interface{}{
						"in":    "header",
						"name":  "X-API-Key",
						"value": "test-token",
					},
				},
				"api": `openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
servers:
  - url: https://api.example.com
paths:
  /test:
    post:
      operationId: testPost
      summary: Test POST endpoint
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - data
              properties:
                data:
                  type: string`,
			},
		},
		"promptTemplate": map[string]interface{}{
			"language": "CH",
		},
	})
	return data
}()

// 测试配置：缺少必需字段
var missingRequiredFieldsConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"llm": map[string]interface{}{
			"apiKey": "test-api-key",
			// 缺少 serviceName, servicePort, domain, path, model
		},
		// 缺少 apis
	})
	return data
}()

// 测试配置：空APIs数组
var emptyAPIsConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"llm": map[string]interface{}{
			"apiKey":      "test-api-key",
			"serviceName": "llm-service",
			"servicePort": 8080,
			"domain":      "llm.example.com",
			"path":        "/v1/chat/completions",
			"model":       "qwen-turbo",
		},
		"apis": []map[string]interface{}{},
	})
	return data
}()

// 测试配置：缺少API提供者信息
var missingAPIProviderConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"llm": map[string]interface{}{
			"apiKey":      "test-api-key",
			"serviceName": "llm-service",
			"servicePort": 8080,
			"domain":      "llm.example.com",
			"path":        "/v1/chat/completions",
			"model":       "qwen-turbo",
		},
		"apis": []map[string]interface{}{
			{
				"api": `openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
servers:
  - url: https://api.example.com
paths:
  /test:
    get:
      operationId: testGet
      summary: Test endpoint`,
			},
		},
	})
	return data
}()

// 测试配置：用于HTTP请求测试的简化配置
var httpTestConfig = func() json.RawMessage {
	data, _ := json.Marshal(map[string]interface{}{
		"returnResponseTemplate": `{"id":"error","choices":[{"index":0,"message":{"role":"assistant","content":"%s"},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}}`,
		"llm": map[string]interface{}{
			"apiKey":      "test-api-key",
			"serviceName": "llm-service",
			"servicePort": 8080,
			"domain":      "llm.example.com",
			"path":        "/v1/chat/completions",
			"model":       "qwen-turbo",
		},
		"apis": []map[string]interface{}{
			{
				"apiProvider": map[string]interface{}{
					"serviceName": "api-service",
					"servicePort": 9090,
					"domain":      "api.example.com",
					"apiKey": map[string]interface{}{
						"in":    "header",
						"name":  "Authorization",
						"value": "Bearer test-token",
					},
				},
				"api": `openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
servers:
  - url: https://api.example.com
paths:
  /weather:
    get:
      operationId: getWeather
      summary: Get weather information
      parameters:
        - name: city
          in: query
          required: true
          schema:
            type: string`,
			},
		},
		"promptTemplate": map[string]interface{}{
			"language": "EN",
		},
	})
	return data
}()

func TestParseConfig(t *testing.T) {
	test.RunGoTest(t, func(t *testing.T) {

		// 测试最小配置解析（使用默认值）
		t.Run("minimal config with defaults", func(t *testing.T) {
			host, status := test.NewTestHost(minimalConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			configRaw, err := host.GetMatchConfig()
			require.NoError(t, err)
			require.NotNil(t, configRaw)

			config, ok := configRaw.(*PluginConfig)
			require.True(t, ok, "config should be of type *PluginConfig")

			// 验证默认响应模板
			require.Contains(t, config.ReturnResponseTemplate, "gpt-4o")

			// 验证LLM默认值
			require.Equal(t, int64(15), config.LLMInfo.MaxIterations)
			require.Equal(t, int64(50000), config.LLMInfo.MaxExecutionTime)
			require.Equal(t, int64(1000), config.LLMInfo.MaxTokens)

			// 验证API默认值
			require.Equal(t, int64(50000), config.APIsParam[0].MaxExecutionTime)

			// 验证提示模板默认值
			require.Equal(t, "EN", config.PromptTemplate.Language)
			require.Equal(t, "input question to answer", config.PromptTemplate.ENTemplate.Question)
			require.Equal(t, "consider previous and subsequent steps", config.PromptTemplate.ENTemplate.Thought1)
			require.Equal(t, "action result", config.PromptTemplate.ENTemplate.Observation)
			require.Equal(t, "I know what to respond", config.PromptTemplate.ENTemplate.Thought2)

			// 验证JSON响应默认值
			require.False(t, config.JsonResp.Enable)
		})

		// 测试中文提示模板配置
		t.Run("chinese prompt template config", func(t *testing.T) {
			host, status := test.NewTestHost(chinesePromptConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			configRaw, err := host.GetMatchConfig()
			require.NoError(t, err)
			require.NotNil(t, configRaw)

			config, ok := configRaw.(*PluginConfig)
			require.True(t, ok, "config should be of type *PluginConfig")

			// 验证中文提示模板
			require.Equal(t, "CH", config.PromptTemplate.Language)
			require.Equal(t, "输入要回答的问题", config.PromptTemplate.CHTemplate.Question)
			require.Equal(t, "考虑之前和之后的步骤", config.PromptTemplate.CHTemplate.Thought1)
			require.Equal(t, "行动结果", config.PromptTemplate.CHTemplate.Observation)
			require.Equal(t, "我知道该回应什么", config.PromptTemplate.CHTemplate.Thought2)
		})

		// 测试缺少必需字段的配置
		t.Run("missing required fields config", func(t *testing.T) {
			host, status := test.NewTestHost(missingRequiredFieldsConfig)
			defer host.Reset()
			// 由于缺少必需字段（apis），配置应该失败
			require.Equal(t, types.OnPluginStartStatusFailed, status)
		})

		// 测试空APIs数组配置
		t.Run("empty APIs config", func(t *testing.T) {
			host, status := test.NewTestHost(emptyAPIsConfig)
			defer host.Reset()
			// 空APIs数组应该导致配置解析失败
			require.Equal(t, types.OnPluginStartStatusFailed, status)
		})

		// 测试缺少API提供者信息的配置
		t.Run("missing API provider config", func(t *testing.T) {
			host, status := test.NewTestHost(missingAPIProviderConfig)
			defer host.Reset()
			// 缺少API提供者信息应该导致配置解析失败
			require.Equal(t, types.OnPluginStartStatusFailed, status)
		})
	})
}

func TestOnHttpRequestHeaders(t *testing.T) {
	test.RunTest(t, func(t *testing.T) {
		t.Run("basic request headers", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			action := host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// onHttpRequestHeaders应该返回ActionContinue
			require.Equal(t, types.ActionContinue, action)
		})
	})
}

func TestOnHttpRequestBody(t *testing.T) {
	test.RunTest(t, func(t *testing.T) {
		t.Run("valid request body with single message", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 构造有效的请求体
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`

			// 调用请求体处理
			action := host.CallOnHttpRequestBody([]byte(requestBody))

			// 应该返回ActionContinue，因为需要等待LLM响应
			require.Equal(t, types.ActionContinue, action)

			// 验证请求体是否被正确修改
			modifiedBody := host.GetRequestBody()
			require.NotNil(t, modifiedBody)

			// 解析修改后的请求体
			var modifiedRequest Request
			err := json.Unmarshal(modifiedBody, &modifiedRequest)
			require.NoError(t, err)

			// 验证消息是否被正确设置
			require.Len(t, modifiedRequest.Messages, 1)
			require.Equal(t, "user", modifiedRequest.Messages[0].Role)
			require.Contains(t, modifiedRequest.Messages[0].Content, "今天天气怎么样？")

			// 验证stream是否被设置为false
			require.False(t, modifiedRequest.Stream)
		})

		t.Run("request body with conversation history", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 构造包含对话历史的请求体
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "你好"
					},
					{
						"role": "assistant",
						"content": "你好！有什么可以帮助你的吗？"
					},
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`

			// 调用请求体处理
			action := host.CallOnHttpRequestBody([]byte(requestBody))

			// 应该返回ActionContinue
			require.Equal(t, types.ActionContinue, action)

			// 验证请求体是否被正确修改
			modifiedBody := host.GetRequestBody()
			require.NotNil(t, modifiedBody)

			// 解析修改后的请求体
			var modifiedRequest Request
			err := json.Unmarshal(modifiedBody, &modifiedRequest)
			require.NoError(t, err)

			// 验证消息是否被正确设置
			require.Len(t, modifiedRequest.Messages, 1)
			require.Equal(t, "user", modifiedRequest.Messages[0].Role)
			require.Contains(t, modifiedRequest.Messages[0].Content, "今天天气怎么样？")
		})

		t.Run("stream request body", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 构造流式请求体
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "流式响应测试"
					}
				],
				"stream": true
			}`

			// 调用请求体处理
			action := host.CallOnHttpRequestBody([]byte(requestBody))

			// 应该返回ActionContinue
			require.Equal(t, types.ActionContinue, action)

			// 验证请求体是否被正确修改
			modifiedBody := host.GetRequestBody()
			require.NotNil(t, modifiedBody)

			// 解析修改后的请求体
			var modifiedRequest Request
			err := json.Unmarshal(modifiedBody, &modifiedRequest)
			require.NoError(t, err)

			// 验证stream是否被设置为false
			require.False(t, modifiedRequest.Stream)
		})

		t.Run("empty messages array", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 构造空消息数组的请求体
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [],
				"stream": false
			}`

			// 调用请求体处理
			action := host.CallOnHttpRequestBody([]byte(requestBody))

			// 应该返回ActionContinue，因为没有消息需要处理
			require.Equal(t, types.ActionContinue, action)
		})

		t.Run("invalid JSON request body", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 构造无效JSON的请求体
			invalidJSON := []byte(`{"model": "qwen-turbo", "messages": [{"role": "user", "content": "test"}`)

			// 调用请求体处理
			action := host.CallOnHttpRequestBody(invalidJSON)

			// 应该返回ActionContinue，因为JSON解析失败
			require.Equal(t, types.ActionContinue, action)
		})

		t.Run("empty content in message", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 构造空内容的请求体
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": ""
					}
				],
				"stream": false
			}`

			// 调用请求体处理
			action := host.CallOnHttpRequestBody([]byte(requestBody))

			// 应该返回ActionContinue，因为内容为空
			require.Equal(t, types.ActionContinue, action)
		})
	})
}

func TestOnHttpResponseBody(t *testing.T) {
	test.RunTest(t, func(t *testing.T) {
		t.Run("valid LLM response with content", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 构造有效的LLM响应体
			responseBody := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"getWeather\", \"action_input\": \"{\\\"city\\\": \\\"北京\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 20,
					"total_tokens": 30
				}
			}`

			// 调用响应体处理
			action := host.CallOnHttpResponseBody([]byte(responseBody))

			// 应该返回ActionPause，因为需要等待工具调用结果
			require.Equal(t, types.ActionPause, action)

			// 模拟API工具调用的响应
			apiResponse := `{"temperature": 25, "condition": "晴朗", "humidity": 60}`
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(apiResponse))

			// 模拟LLM对工具调用结果的响应（Final Answer）
			llmFinalResponse := `{
				"id": "chatcmpl-124",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "Final Answer: 今天北京天气晴朗，温度25度，湿度60%"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652289,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 15,
					"completion_tokens": 25,
					"total_tokens": 40
				}
			}`

			// 模拟LLM客户端的响应
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(llmFinalResponse))

			// 完成HTTP请求
			host.CompleteHttp()
		})

		t.Run("LLM response with Final Answer", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 构造包含Final Answer的LLM响应体
			responseBody := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "Final Answer: 今天北京天气晴朗，温度25度"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 20,
					"total_tokens": 30
				}
			}`

			// 调用响应体处理
			action := host.CallOnHttpResponseBody([]byte(responseBody))

			// 应该返回ActionContinue，因为得到了Final Answer
			require.Equal(t, types.ActionContinue, action)
		})

		t.Run("LLM response with empty content", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 构造空内容的LLM响应体
			responseBody := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": ""
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 0,
					"total_tokens": 10
				}
			}`

			// 调用响应体处理
			action := host.CallOnHttpResponseBody([]byte(responseBody))

			// 应该返回ActionContinue，因为内容为空
			require.Equal(t, types.ActionContinue, action)
		})

		t.Run("invalid LLM response JSON", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 构造无效JSON的响应体
			invalidJSON := []byte(`{"id": "chatcmpl-123", "choices": [{"index": 0, "message": {"role": "assistant", "content": "test"}`)

			// 调用响应体处理
			action := host.CallOnHttpResponseBody(invalidJSON)

			// 应该返回ActionContinue，因为JSON解析失败
			require.Equal(t, types.ActionContinue, action)
		})

		t.Run("complete ReAct loop flow", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "查询北京和上海的天气"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 第一次LLM响应，要求调用工具查询北京天气
			llmResponse1 := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"getWeather\", \"action_input\": \"{\\\"city\\\": \\\"北京\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 20,
					"total_tokens": 30
				}
			}`

			// 调用响应体处理，这会触发toolsCall
			action := host.CallOnHttpResponseBody([]byte(llmResponse1))

			// 应该返回ActionPause，因为需要等待工具调用结果
			require.Equal(t, types.ActionPause, action)

			// 模拟API工具调用的响应（北京天气）
			apiResponse1 := `{"temperature": 25, "condition": "晴朗", "humidity": 60}`
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(apiResponse1))

			// 第二次LLM响应，要求调用工具查询上海天气
			llmResponse2 := `{
				"id": "chatcmpl-124",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"getWeather\", \"action_input\": \"{\\\"city\\\": \\\"上海\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652289,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 15,
					"completion_tokens": 25,
					"total_tokens": 40
				}
			}`

			// 模拟LLM客户端的响应
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(llmResponse2))

			// 模拟API工具调用的响应（上海天气）
			apiResponse2 := `{"temperature": 28, "condition": "多云", "humidity": 70}`
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(apiResponse2))

			// 第三次LLM响应，给出Final Answer
			llmResponse3 := `{
				"id": "chatcmpl-125",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "Final Answer: 北京今天天气晴朗，温度25度，湿度60%；上海今天天气多云，温度28度，湿度70%"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652290,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 20,
					"completion_tokens": 30,
					"total_tokens": 50
				}
			}`

			// 模拟LLM客户端的响应
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(llmResponse3))

			// 完成HTTP请求
			host.CompleteHttp()
		})
	})
}

func TestFirstReq(t *testing.T) {
	test.RunTest(t, func(t *testing.T) {
		t.Run("successful request body replacement", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 构造原始请求
			originalRequest := Request{
				Model: "qwen-turbo",
				Messages: []Message{
					{
						Role:    "user",
						Content: "原始消息",
					},
				},
				Stream: true,
			}

			// 调用firstReq（通过onHttpRequestBody间接调用）
			requestBody, _ := json.Marshal(originalRequest)
			action := host.CallOnHttpRequestBody(requestBody)

			// 应该返回ActionContinue
			require.Equal(t, types.ActionContinue, action)

			// 验证请求体是否被正确修改
			modifiedBody := host.GetRequestBody()
			require.NotNil(t, modifiedBody)

			// 解析修改后的请求体
			var modifiedRequest Request
			err := json.Unmarshal(modifiedBody, &modifiedRequest)
			require.NoError(t, err)

			// 验证stream是否被设置为false
			require.False(t, modifiedRequest.Stream)

			// 验证消息是否被正确设置
			require.Len(t, modifiedRequest.Messages, 1)
			require.Equal(t, "user", modifiedRequest.Messages[0].Role)
			require.Contains(t, modifiedRequest.Messages[0].Content, "原始消息")
		})
	})
}

func TestToolsCall(t *testing.T) {
	test.RunTest(t, func(t *testing.T) {
		t.Run("GET tool call with complete flow", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 模拟LLM响应，要求调用GET工具
			llmResponse := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"getWeather\", \"action_input\": \"{\\\"city\\\": \\\"北京\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 20,
					"total_tokens": 30
				}
			}`

			// 调用响应体处理，这会触发toolsCall
			action := host.CallOnHttpResponseBody([]byte(llmResponse))

			// 应该返回ActionPause，因为需要等待工具调用结果
			require.Equal(t, types.ActionPause, action)

			// 模拟API工具调用的响应
			apiResponse := `{"temperature": 25, "condition": "晴朗"}`
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(apiResponse))

			// 模拟LLM对工具调用结果的响应（Final Answer）
			llmFinalResponse := `{
				"id": "chatcmpl-124",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "Final Answer: 今天北京天气晴朗，温度25度，湿度60%"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652289,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 15,
					"completion_tokens": 25,
					"total_tokens": 40
				}
			}`

			// 模拟LLM客户端的响应
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(llmFinalResponse))

			// 完成HTTP请求
			host.CompleteHttp()
		})

		t.Run("POST tool call with complete flow", func(t *testing.T) {
			// 创建一个支持POST工具的配置
			postToolConfig := func() json.RawMessage {
				data, _ := json.Marshal(map[string]interface{}{
					"returnResponseTemplate": `{"id":"error","choices":[{"index":0,"message":{"role":"assistant","content":"%s"},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}}`,
					"llm": map[string]interface{}{
						"apiKey":      "test-api-key",
						"serviceName": "llm-service",
						"servicePort": 8080,
						"domain":      "llm.example.com",
						"path":        "/v1/chat/completions",
						"model":       "qwen-turbo",
					},
					"apis": []map[string]interface{}{
						{
							"apiProvider": map[string]interface{}{
								"serviceName": "api-service",
								"servicePort": 9090,
								"domain":      "api.example.com",
								"apiKey": map[string]interface{}{
									"in":    "header",
									"name":  "Authorization",
									"value": "Bearer test-token",
								},
							},
							"api": `openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
servers:
  - url: https://api.example.com
paths:
  /translate:
    post:
      operationId: translateText
      summary: Translate text
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required:
                - text
                - targetLang
              properties:
                text:
                  type: string
                targetLang:
                  type: string`,
						},
					},
					"promptTemplate": map[string]interface{}{
						"language": "EN",
					},
				})
				return data
			}()

			host, status := test.NewTestHost(postToolConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "翻译这段文字"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 模拟LLM响应，要求调用POST工具
			llmResponse := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"translateText\", \"action_input\": \"{\\\"text\\\": \\\"Hello\\\", \\\"targetLang\\\": \\\"zh\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 20,
					"total_tokens": 30
				}
			}`

			// 调用响应体处理，这会触发toolsCall
			action := host.CallOnHttpResponseBody([]byte(llmResponse))

			// 应该返回ActionPause，因为需要等待工具调用结果
			require.Equal(t, types.ActionPause, action)

			// 模拟API工具调用的响应
			apiResponse := `{"translatedText": "你好", "sourceLang": "en", "targetLang": "zh"}`
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(apiResponse))

			// 模拟LLM对工具调用结果的响应（Final Answer）
			llmFinalResponse := `{
				"id": "chatcmpl-124",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "Final Answer: Hello翻译成中文是：你好"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652289,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 15,
					"completion_tokens": 25,
					"total_tokens": 40
				}
			}`

			// 模拟LLM客户端的响应
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(llmFinalResponse))

			// 完成HTTP请求
			host.CompleteHttp()
		})

		t.Run("Final Answer response", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 模拟LLM响应，直接给出Final Answer
			llmResponse := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "Final Answer: 今天北京天气晴朗，温度25度"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 20,
					"total_tokens": 30
				}
			}`

			// 调用响应体处理，这会触发toolsCall
			action := host.CallOnHttpResponseBody([]byte(llmResponse))

			// 应该返回ActionContinue，因为得到了Final Answer
			require.Equal(t, types.ActionContinue, action)
		})

		t.Run("unknown tool name", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "调用一个工具"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 模拟LLM响应，要求调用未知工具
			llmResponse := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"unknownTool\", \"action_input\": \"{\\\"param\\\": \\\"value\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 20,
					"total_tokens": 30
				}
			}`

			// 调用响应体处理，这会触发toolsCall
			action := host.CallOnHttpResponseBody([]byte(llmResponse))

			// 应该返回ActionContinue，因为工具名称未知
			require.Equal(t, types.ActionContinue, action)
		})

		t.Run("tool call with max iterations", func(t *testing.T) {
			// 创建一个设置最大迭代次数为2的配置
			maxIterConfig := func() json.RawMessage {
				data, _ := json.Marshal(map[string]interface{}{
					"returnResponseTemplate": `{"id":"error","choices":[{"index":0,"message":{"role":"assistant","content":"%s"},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}}`,
					"llm": map[string]interface{}{
						"apiKey":        "test-api-key",
						"serviceName":   "llm-service",
						"servicePort":   8080,
						"domain":        "llm.example.com",
						"path":          "/v1/chat/completions",
						"model":         "qwen-turbo",
						"maxIterations": 2,
					},
					"apis": []map[string]interface{}{
						{
							"apiProvider": map[string]interface{}{
								"serviceName": "api-service",
								"servicePort": 9090,
								"domain":      "api.example.com",
								"apiKey": map[string]interface{}{
									"in":    "header",
									"name":  "Authorization",
									"value": "Bearer test-token",
								},
							},
							"api": `openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
servers:
  - url: https://api.example.com
paths:
  /weather:
    get:
      operationId: getWeather
      summary: Get weather information
      parameters:
        - name: city
          in: query
          required: true
          schema:
            type: string`,
						},
					},
					"promptTemplate": map[string]interface{}{
						"language": "EN",
					},
				})
				return data
			}()

			host, status := test.NewTestHost(maxIterConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 第一次LLM响应，要求调用工具
			llmResponse1 := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"getWeather\", \"action_input\": \"{\\\"city\\\": \\\"北京\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 20,
					"total_tokens": 30
				}
			}`

			// 调用响应体处理，这会触发toolsCall
			action := host.CallOnHttpResponseBody([]byte(llmResponse1))

			// 应该返回ActionPause，因为需要等待工具调用结果
			require.Equal(t, types.ActionPause, action)

			// 模拟API工具调用的响应
			apiResponse := `{"temperature": 25, "condition": "晴朗"}`
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(apiResponse))

			// 第二次LLM响应，再次要求调用工具
			llmResponse2 := `{
				"id": "chatcmpl-124",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"getWeather\", \"action_input\": \"{\\\"city\\\": \\\"上海\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652289,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 15,
					"completion_tokens": 25,
					"total_tokens": 40
				}
			}`

			// 模拟LLM客户端的响应
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(llmResponse2))

			// 第三次LLM响应，应该因为达到最大迭代次数而返回ActionContinue
			llmResponse3 := `{
				"id": "chatcmpl-125",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"getWeather\", \"action_input\": \"{\\\"city\\\": \\\"广州\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652290,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 20,
					"completion_tokens": 30,
					"total_tokens": 50
				}
			}`

			// 模拟LLM客户端的响应
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(llmResponse3))

			// 完成HTTP请求
			host.CompleteHttp()
		})
	})
}

func TestEdgeCases(t *testing.T) {
	test.RunTest(t, func(t *testing.T) {
		t.Run("max iterations exceeded", func(t *testing.T) {
			// 创建一个设置最大迭代次数为1的配置
			maxIterConfig := func() json.RawMessage {
				data, _ := json.Marshal(map[string]interface{}{
					"returnResponseTemplate": `{"id":"error","choices":[{"index":0,"message":{"role":"assistant","content":"%s"},"finish_reason":"stop"}],"model":"gpt-4o","object":"chat.completion","usage":{"prompt_tokens":0,"completion_tokens":0,"total_tokens":0}}`,
					"llm": map[string]interface{}{
						"apiKey":        "test-api-key",
						"serviceName":   "llm-service",
						"servicePort":   8080,
						"domain":        "llm.example.com",
						"path":          "/v1/chat/completions",
						"model":         "qwen-turbo",
						"maxIterations": 1,
					},
					"apis": []map[string]interface{}{
						{
							"apiProvider": map[string]interface{}{
								"serviceName": "api-service",
								"servicePort": 9090,
								"domain":      "api.example.com",
								"apiKey": map[string]interface{}{
									"in":    "header",
									"name":  "Authorization",
									"value": "Bearer test-token",
								},
							},
							"api": `openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
servers:
  - url: https://api.example.com
paths:
  /weather:
    get:
      operationId: getWeather
      summary: Get weather information
      parameters:
        - name: city
          in: query
          required: true
          schema:
            type: string`,
						},
					},
					"promptTemplate": map[string]interface{}{
						"language": "EN",
					},
				})
				return data
			}()

			host, status := test.NewTestHost(maxIterConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 模拟LLM响应，要求调用工具
			llmResponse := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"getWeather\", \"action_input\": \"{\\\"city\\\": \\\"北京\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 20,
					"total_tokens": 30
				}
			}`

			// 调用响应体处理，这会触发toolsCall
			action := host.CallOnHttpResponseBody([]byte(llmResponse))

			// 应该返回ActionPause，因为需要等待工具调用结果
			require.Equal(t, types.ActionPause, action)

			// 模拟API工具调用的响应
			apiResponse := `{"temperature": 25, "condition": "晴朗"}`
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(apiResponse))

			// 模拟LLM对工具调用结果的响应，再次要求调用工具
			llmResponse2 := `{
				"id": "chatcmpl-124",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"getWeather\", \"action_input\": \"{\\\"city\\\": \\\"上海\\\"}\"}"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652289,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 15,
					"completion_tokens": 25,
					"total_tokens": 40
				}
			}`

			// 模拟LLM客户端的响应
			host.CallOnHttpCall([][2]string{
				{"Content-Type", "application/json"},
				{":status", "200"},
			}, []byte(llmResponse2))

			// 完成HTTP请求
			host.CompleteHttp()
		})

		t.Run("invalid action input JSON", func(t *testing.T) {
			host, status := test.NewTestHost(httpTestConfig)
			defer host.Reset()
			require.Equal(t, types.OnPluginStartStatusOK, status)

			// 设置请求头
			host.CallOnHttpRequestHeaders([][2]string{
				{":authority", "example.com"},
				{":path", "/api/chat"},
				{":method", "POST"},
				{"content-type", "application/json"},
			})

			// 先调用请求体处理来初始化上下文
			requestBody := `{
				"model": "qwen-turbo",
				"messages": [
					{
						"role": "user",
						"content": "今天天气怎么样？"
					}
				],
				"stream": false
			}`
			host.CallOnHttpRequestBody([]byte(requestBody))

			// 模拟LLM响应，包含无效的Action Input JSON
			llmResponse := `{
				"id": "chatcmpl-123",
				"choices": [
					{
						"index": 0,
						"message": {
							"role": "assistant",
							"content": "{\"action\": \"getWeather\", \"action_input\": {invalid json"
						},
						"finish_reason": "stop"
					}
				],
				"created": 1677652288,
				"model": "qwen-turbo",
				"object": "chat.completion",
				"usage": {
					"prompt_tokens": 10,
					"completion_tokens": 20,
					"total_tokens": 30
				}
			}`

			// 调用响应体处理，这会触发toolsCall
			action := host.CallOnHttpResponseBody([]byte(llmResponse))

			// 应该返回ActionContinue，因为Action Input JSON无效
			require.Equal(t, types.ActionContinue, action)
		})
	})
}
