parent
cdc720df8c
commit
6114f39861
@ -0,0 +1,135 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 CloudWeGo Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/cloudwego/eino/components/tool"
|
||||||
|
"github.com/cloudwego/eino/components/tool/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetWeatherInput struct {
|
||||||
|
Location string `json:"location" jsonschema:"description=The city and state, e.g. San Francisco, CA"`
|
||||||
|
Unit string `json:"unit,omitempty" jsonschema:"enum=celsius,enum=fahrenheit,description=The unit of temperature"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetWeatherOutput struct {
|
||||||
|
Temperature float64 `json:"temperature"`
|
||||||
|
Unit string `json:"unit"`
|
||||||
|
Condition string `json:"condition"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetForecastInput struct {
|
||||||
|
Location string `json:"location" jsonschema:"description=The city and state"`
|
||||||
|
Days int `json:"days" jsonschema:"description=Number of days to forecast (1-10)"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetForecastOutput struct {
|
||||||
|
Forecasts []DayForecast `json:"forecasts"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DayForecast struct {
|
||||||
|
Day string `json:"day"`
|
||||||
|
Temperature float64 `json:"temperature"`
|
||||||
|
Condition string `json:"condition"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetStockPriceInput struct {
|
||||||
|
Ticker string `json:"ticker" jsonschema:"description=Stock ticker symbol (e.g., AAPL, GOOGL)"`
|
||||||
|
IncludeHistory bool `json:"include_history,omitempty" jsonschema:"description=Include historical data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetStockPriceOutput struct {
|
||||||
|
Ticker string `json:"ticker"`
|
||||||
|
Price float64 `json:"price"`
|
||||||
|
Change float64 `json:"change"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConvertCurrencyInput struct {
|
||||||
|
Amount float64 `json:"amount" jsonschema:"description=Amount to convert"`
|
||||||
|
FromCurrency string `json:"from_currency" jsonschema:"description=Source currency code (e.g., USD)"`
|
||||||
|
ToCurrency string `json:"to_currency" jsonschema:"description=Target currency code (e.g., EUR)"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ConvertCurrencyOutput struct {
|
||||||
|
OriginalAmount float64 `json:"original_amount"`
|
||||||
|
ConvertedAmount float64 `json:"converted_amount"`
|
||||||
|
ExchangeRate float64 `json:"exchange_rate"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func createWeatherTools() []tool.BaseTool {
|
||||||
|
getWeather, _ := utils.InferTool(
|
||||||
|
"get_weather",
|
||||||
|
"Get the current weather in a given location",
|
||||||
|
func(ctx context.Context, input *GetWeatherInput) (*GetWeatherOutput, error) {
|
||||||
|
return &GetWeatherOutput{
|
||||||
|
Temperature: 22.5,
|
||||||
|
Unit: input.Unit,
|
||||||
|
Condition: "Sunny",
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
getForecast, _ := utils.InferTool(
|
||||||
|
"get_forecast",
|
||||||
|
"Get the weather forecast for multiple days ahead",
|
||||||
|
func(ctx context.Context, input *GetForecastInput) (*GetForecastOutput, error) {
|
||||||
|
forecasts := make([]DayForecast, input.Days)
|
||||||
|
for i := 0; i < input.Days; i++ {
|
||||||
|
forecasts[i] = DayForecast{
|
||||||
|
Day: fmt.Sprintf("Day %d", i+1),
|
||||||
|
Temperature: 20.0 + float64(i),
|
||||||
|
Condition: "Partly Cloudy",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &GetForecastOutput{Forecasts: forecasts}, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return []tool.BaseTool{getWeather, getForecast}
|
||||||
|
}
|
||||||
|
|
||||||
|
func createFinanceTools() []tool.BaseTool {
|
||||||
|
getStockPrice, _ := utils.InferTool(
|
||||||
|
"get_stock_price",
|
||||||
|
"Get the current stock price and market data for a given ticker symbol",
|
||||||
|
func(ctx context.Context, input *GetStockPriceInput) (*GetStockPriceOutput, error) {
|
||||||
|
return &GetStockPriceOutput{
|
||||||
|
Ticker: input.Ticker,
|
||||||
|
Price: 150.25,
|
||||||
|
Change: 2.5,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
convertCurrency, _ := utils.InferTool(
|
||||||
|
"convert_currency",
|
||||||
|
"Convert an amount from one currency to another using current exchange rates",
|
||||||
|
func(ctx context.Context, input *ConvertCurrencyInput) (*ConvertCurrencyOutput, error) {
|
||||||
|
rate := 0.85
|
||||||
|
return &ConvertCurrencyOutput{
|
||||||
|
OriginalAmount: input.Amount,
|
||||||
|
ConvertedAmount: input.Amount * rate,
|
||||||
|
ExchangeRate: rate,
|
||||||
|
}, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return []tool.BaseTool{getStockPrice, convertCurrency}
|
||||||
|
}
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 CloudWeGo Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/cloudwego/eino-ext/components/model/ark"
|
||||||
|
"github.com/cloudwego/eino/adk"
|
||||||
|
"github.com/cloudwego/eino/adk/middlewares/dynamictool/toolsearch"
|
||||||
|
|
||||||
|
"github.com/cloudwego/eino-examples/adk/common/prints"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
weatherTools := createWeatherTools()
|
||||||
|
financeTools := createFinanceTools()
|
||||||
|
allDynamicTools := append(weatherTools, financeTools...)
|
||||||
|
|
||||||
|
toolSearchMiddleware, err := toolsearch.New(ctx, &toolsearch.Config{
|
||||||
|
DynamicTools: allDynamicTools,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("failed to create tool search middleware: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
chatModel, err := ark.NewChatModel(ctx, &ark.ChatModelConfig{
|
||||||
|
APIKey: os.Getenv("ARK_API_KEY"),
|
||||||
|
Model: os.Getenv("ARK_MODEL"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
|
||||||
|
Name: "tool_search_agent",
|
||||||
|
Description: "An agent that can dynamically search and use tools from a large tool library",
|
||||||
|
Instruction: `You are a helpful assistant.`,
|
||||||
|
Model: chatModel,
|
||||||
|
Handlers: []adk.ChatModelAgentMiddleware{
|
||||||
|
toolSearchMiddleware,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("failed to create agent: %v\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
runner := adk.NewRunner(ctx, adk.RunnerConfig{
|
||||||
|
Agent: agent,
|
||||||
|
EnableStreaming: true,
|
||||||
|
})
|
||||||
|
iter := runner.Query(ctx, "What's the weather in Beijing?")
|
||||||
|
for {
|
||||||
|
event, ok := iter.Next()
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
prints.Event(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 CloudWeGo Authors
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/cloudwego/eino-ext/adk/backend/local"
|
||||||
|
"github.com/cloudwego/eino-ext/components/model/ark"
|
||||||
|
"github.com/cloudwego/eino/adk"
|
||||||
|
"github.com/cloudwego/eino/adk/middlewares/filesystem"
|
||||||
|
"github.com/cloudwego/eino/adk/middlewares/skill"
|
||||||
|
|
||||||
|
"github.com/cloudwego/eino-examples/adk/common/prints"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
ctx := context.Background()
|
||||||
|
pwd, _ := os.Getwd()
|
||||||
|
workDir := filepath.Join(pwd, "adk", "middlewares", "skill", "workdir")
|
||||||
|
skillsDir := filepath.Join(workDir, "skills")
|
||||||
|
|
||||||
|
cm, err := ark.NewChatModel(ctx, &ark.ChatModelConfig{
|
||||||
|
APIKey: os.Getenv("ARK_API_KEY"),
|
||||||
|
Model: os.Getenv("ARK_MODEL"),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
be, err := local.NewBackend(ctx, &local.Config{})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fsm, err := filesystem.New(ctx, &filesystem.MiddlewareConfig{
|
||||||
|
Backend: be,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
skillBackend, err := skill.NewBackendFromFilesystem(ctx, &skill.BackendFromFilesystemConfig{
|
||||||
|
Backend: be,
|
||||||
|
BaseDir: skillsDir,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to create skill backend: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sm, err := skill.NewMiddleware(ctx, &skill.Config{
|
||||||
|
Backend: skillBackend,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to create skill middleware: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
agent, err := adk.NewChatModelAgent(ctx, &adk.ChatModelAgentConfig{
|
||||||
|
Name: "LogAnalysisAgent",
|
||||||
|
Description: "An agent that can analyze logs",
|
||||||
|
Instruction: "You are a helpful assistant.",
|
||||||
|
Model: cm,
|
||||||
|
Handlers: []adk.ChatModelAgentMiddleware{fsm, sm},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Failed to create agent: %v", err)
|
||||||
|
}
|
||||||
|
runner := adk.NewRunner(ctx, adk.RunnerConfig{
|
||||||
|
Agent: agent,
|
||||||
|
})
|
||||||
|
|
||||||
|
input := fmt.Sprintf("Analyze the %s file", filepath.Join(workDir, "test.log"))
|
||||||
|
log.Println("User: ", input)
|
||||||
|
|
||||||
|
iterator := runner.Query(ctx, input)
|
||||||
|
for {
|
||||||
|
event, ok := iterator.Next()
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if event.Err != nil {
|
||||||
|
log.Printf("Error: %v\n", event.Err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
prints.Event(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
name: log_analyzer
|
||||||
|
description: A skill to analyze log files for errors and warnings using a Python script.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Log Analyzer Skill
|
||||||
|
|
||||||
|
This skill analyzes a log file to count the occurrences of "ERROR" and "WARNING" and lists the lines where they appear.
|
||||||
|
|
||||||
|
## Capability
|
||||||
|
|
||||||
|
The skill provides a Python script named `analyze.py` located in this directory. You can use this script to analyze any text file.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
To use this skill, execute the `analyze.py` script with the target log file as an argument.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 {{.BaseDirectory}}/scripts/analyze.py /path/to/logfile.log
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: Replace `/path/to/logfile.log` with the actual path of the file you want to analyze.
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
def analyze_log(file_path):
|
||||||
|
if not os.path.exists(file_path):
|
||||||
|
print(f"Error: File '{file_path}' not found.")
|
||||||
|
return
|
||||||
|
|
||||||
|
error_count = 0
|
||||||
|
warning_count = 0
|
||||||
|
error_lines = []
|
||||||
|
warning_lines = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(file_path, 'r') as f:
|
||||||
|
for i, line in enumerate(f, 1):
|
||||||
|
content = line.strip()
|
||||||
|
if "ERROR" in content:
|
||||||
|
error_count += 1
|
||||||
|
error_lines.append(f"Line {i}: {content}")
|
||||||
|
elif "WARNING" in content:
|
||||||
|
warning_count += 1
|
||||||
|
warning_lines.append(f"Line {i}: {content}")
|
||||||
|
|
||||||
|
print(f"Analysis Result for {file_path}:")
|
||||||
|
print(f"Total Errors: {error_count}")
|
||||||
|
print(f"Total Warnings: {warning_count}")
|
||||||
|
|
||||||
|
if error_count > 0:
|
||||||
|
print("\nError Details:")
|
||||||
|
for line in error_lines:
|
||||||
|
print(line)
|
||||||
|
|
||||||
|
if warning_count > 0:
|
||||||
|
print("\nWarning Details:")
|
||||||
|
for line in warning_lines:
|
||||||
|
print(line)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"An error occurred while reading the file: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print("Usage: python3 analyze.py <log_file_path>")
|
||||||
|
else:
|
||||||
|
analyze_log(sys.argv[1])
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
[2024-05-20 10:00:00] INFO: Service started.
|
||||||
|
[2024-05-20 10:01:23] WARNING: High memory usage detected.
|
||||||
|
[2024-05-20 10:02:15] ERROR: Database connection failed.
|
||||||
|
[2024-05-20 10:03:00] INFO: Retry connection.
|
||||||
|
[2024-05-20 10:03:05] ERROR: Connection timed out.
|
||||||
|
[2024-05-20 10:05:00] INFO: Service stopped.
|
||||||
Loading…
Reference in New Issue