Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions backend/modules/observability/lib/otel/consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ const (
otelAttributeToolsPrefix = "gen_ai.request.functions" // tools
)

// otel attribute key
const (
otelAttributeModelInputTools = "gen_ai.tool.definitions"
)

var otelMessageEventNameMap = []string{
otelEventModelSystemMessage,
otelEventModelUserMessage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,17 @@ func convertModelMsg(msg map[string]interface{}) map[string]interface{} {
// get tool_call
toolCall, ok := tc["tool_call"].(map[string]interface{})
if !ok {
continue
toolCall = tc // maybe no tool_call key, it has been a raw tool_call
}
// get function from tool_call
function, ok := toolCall["function"].(map[string]interface{})
if !ok {
continue
}

id, _ := toolCall["id"]
modelCall := map[string]interface{}{
"type": "function",
"id": id,
"function": map[string]interface{}{
"name": function["name"],
},
Expand Down
60 changes: 60 additions & 0 deletions backend/modules/observability/lib/otel/open_telemetry/otel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2026 coze-dev Authors
// SPDX-License-Identifier: Apache-2.0

package open_telemetry

import "fmt"

func AddTools2ModelInput(input interface{}, tools interface{}) (interface{}, error) {
modelInput, ok := input.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("input is not a map")
}

toolsSlice, ok := tools.([]interface{})
if !ok {
return modelInput, nil
}

modelTools := make([]interface{}, 0, len(toolsSlice))
for _, tool := range toolsSlice {
toolMap, ok := tool.(map[string]interface{})
if !ok {
continue
}

function, ok := toolMap["function"].(map[string]interface{})
if !ok {
function = toolMap // maybe no function key, it has been a raw function
}

name, _ := function["name"]
if name == nil {
name = ""
}
description, _ := function["description"]
if description == nil {
description = ""
}
parameters, _ := function["parameters"]
if parameters == nil {
parameters = "{}"
}
modelTool := map[string]interface{}{
"type": "function",
"function": map[string]interface{}{
"name": name,
"description": description,
"parameters": parameters,
},
}

modelTools = append(modelTools, modelTool)
}

if len(modelTools) > 0 {
modelInput["tools"] = modelTools
}

return modelInput, nil
}
15 changes: 12 additions & 3 deletions backend/modules/observability/lib/otel/otel_convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/bytedance/sonic"
"github.com/coze-dev/coze-loop/backend/modules/observability/lib/otel/litellm"
"github.com/coze-dev/coze-loop/backend/modules/observability/lib/otel/open_inference"
"github.com/coze-dev/coze-loop/backend/modules/observability/lib/otel/open_telemetry"
"github.com/coze-dev/cozeloop-go/spec/tracespec"
semconv "go.opentelemetry.io/otel/semconv/v1.37.0"

Expand Down Expand Up @@ -673,9 +674,17 @@ func processAttributePrefix(ctx context.Context, fieldKey string, conf FieldConf
}
// pack tools
srcTools := aggregateAttributesByPrefix(attributeMap, openInferenceAttributeModelInputTools)
toBeMarshalObject, err = open_inference.AddTools2ModelInput(srcInput, srcTools)
if err != nil {
continue
if srcTools != nil { // openInference tools
toBeMarshalObject, err = open_inference.AddTools2ModelInput(srcInput, srcTools)
if err != nil {
continue
}
} else { // otel tools
srcTools = aggregateAttributesByPrefix(attributeMap, otelAttributeModelInputTools)
toBeMarshalObject, err = open_telemetry.AddTools2ModelInput(srcInput, srcTools)
if err != nil {
continue
}
}
case openInferenceAttributeModelOutputMessages: // openInference output message
resObject, err := open_inference.ConvertToModelOutput(srcAttrAggrRes)
Expand Down
Loading