This commit is contained in:
lik
2026-09-09 17:36:25 +08:00
parent 1f2da22cae
commit d6efb180dd
54 changed files with 0 additions and 2000 deletions
@@ -0,0 +1,42 @@
import { tool } from "langchain"
import lunar from "lunar-javascript"
const { Solar, Lunar, HolidayUtil, TermUtil } = lunar
import { getAccurateTime } from "./utils.js"
/**
* 日历工具
* 提供准确时间、农历信息、节气、节日和老黄历等信息
*/
export const getCalendarInfoTool = tool(
async () => {
try {
// 获取准确时间
const timeInfo = await getAccurateTime()
// 获取农历信息
const date = new Date(timeInfo.timestamp)
const solar = Solar.fromDate(date)
const lunar = solar.getLunar()
// 组合返回结果
const result = {
time: timeInfo,
weekday: solar.getWeek(),
lunar: {
lunar: lunar.toString(),
solar: solar.toString(),
}
}
return JSON.stringify(result, null, 2)
} catch (error) {
console.error('Error in calendar tool:', error)
return JSON.stringify({ error: error.message }, null, 2)
}
},
{
name: "get_calendar_info",
description: "获取当前准确日期时间,以及对应的农历日期"
}
)
@@ -0,0 +1,62 @@
import { tool } from "langchain"
import lunarLib from "lunar-javascript"
const { Solar } = lunarLib
/**
* 特定日期日历工具
* 基于 lunar-javascript 提供指定日期的完整农历信息
*/
export const getLunarCalendarInfoTool = tool(
async ({ year, month, day }) => {
try {
const solar = Solar.fromYmd(year, month, day)
const lunar = solar.getLunar()
const result = {
solar: solar.toString(),
weekday: `星期${solar.getWeekInChinese()}`,
lunar: lunar.toString(),
ganzhiYear: lunar.getYearInGanZhi(),
zodiac: lunar.getYearShengXiao(),
solarTerms: lunar.getJieQi() || null,
festivals: [...solar.getFestivals(), ...lunar.getFestivals()],
yi: lunar.getDayYi(),
ji: lunar.getDayJi(),
xiShen: lunar.getDayPositionXiDesc(),
caiShen: lunar.getDayPositionCaiDesc()
}
return JSON.stringify(result, null, 2)
} catch (error) {
return JSON.stringify({ error: error.message }, null, 2)
}
},
{
name: "get_lunar_calendar_info",
description: "获取指定日期的日历信息,包括农历信息、老黄历、当年生肖、今日宜忌、喜神方位、财神方位、今日节气、今日节日等",
schema: {
type: "object",
properties: {
year: {
type: "number",
description: "年份",
minimum: 1900,
maximum: 2100
},
month: {
type: "number",
description: "月份",
minimum: 1,
maximum: 12
},
day: {
type: "number",
description: "日期",
minimum: 1,
maximum: 31
}
},
required: ["year", "month", "day"]
}
}
)
+87
View File
@@ -0,0 +1,87 @@
import * as z from "zod"
import { tool } from "langchain"
import lunar from "lunar-javascript"
const { Solar, Lunar, HolidayUtil, TermUtil } = lunar
/**
* 获取准确时间工具
* 通过国内权威时间源获取当前准确时间
* @returns {string} - 返回当前准确时间的JSON字符串
*/
export async function getAccurateTime() {
const timeSources = [
{
name: 'timeapi.io',
url: 'https://timeapi.io/api/Time/current/zone?timeZone=Asia/Shanghai',
method: 'json'
},
{
name: '国家授时中心',
url: 'http://www.ntsc.ac.cn',
method: 'header'
},
{
name: '阿里云',
url: 'https://www.aliyun.com',
method: 'header'
},
{
name: '腾讯云',
url: 'https://cloud.tencent.com',
method: 'header'
},
{
name: '华为云',
url: 'https://www.huaweicloud.com',
method: 'header'
}
]
for (const source of timeSources) {
try {
const startTime = Date.now()
// 每个时间源限时 3 秒,防止单个源 TCP 挂起长时间阻塞
const res = await fetch(source.url, { signal: AbortSignal.timeout(3000) })
const latency = Date.now() - startTime
let timestamp = null
let beijingTime = null
if (source.method === 'json') {
const data = await res.json()
timestamp = new Date(data.dateTime).getTime()
beijingTime = data.dateTime
} else if (source.method === 'header') {
const dateHeader = res.headers.get('Date')
if (dateHeader) {
timestamp = new Date(dateHeader).getTime()
beijingTime = new Date(timestamp).toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' })
}
}
if (timestamp) {
return {
timestamp,
date: new Date(timestamp).toISOString(),
localTime: beijingTime,
source: source.name,
latency: latency,
success: true
}
}
} catch (error) {
console.log(`${source.name} 获取时间失败: ${error.message}`)
continue
}
}
const date = new Date()
return {
timestamp: date.getTime(),
date: date.toISOString(),
localTime: date.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }),
success: false,
message: '使用本地时间作为备份'
}
}
@@ -0,0 +1,52 @@
import { tool } from "langchain"
import lunarLib from "lunar-javascript"
const { Solar, HolidayUtil } = lunarLib
/**
* 年份节日列表工具
* 基于 lunar-javascript 计算全年节日(公历节日 + 农历传统节日)与法定节假日安排
*/
export const getYearHolidaysTool = tool(
async ({ year }) => {
try {
// 法定节假日安排(含调休补班)
const legal = HolidayUtil.getHolidays(year).map(h => ({
date: h.getTarget().toString(),
name: h.getName(),
type: h.isWork() ? "调休上班" : "放假"
}))
// 遍历全年日期,收集公历节日与农历传统节日(春节、中秋、端午等)
const festivals = []
const start = Solar.fromYmd(year, 1, 1)
const days = Solar.fromYmd(year + 1, 1, 1).subtract(start)
for (let i = 0; i < days; i++) {
const d = start.next(i)
const names = [...d.getFestivals(), ...d.getLunar().getFestivals()]
if (names.length) {
festivals.push({ date: d.toString(), name: names.join("、") })
}
}
return JSON.stringify({ year, legal, festivals }, null, 2)
} catch (error) {
return JSON.stringify({ error: error.message }, null, 2)
}
},
{
name: "get_year_holidays",
description: "查询给定年份节日所在日期列表,包括法定节假日安排(含调休)与传统节日",
schema: {
type: "object",
properties: {
year: {
type: "number",
description: "年份",
minimum: 1900,
maximum: 2100
}
},
required: ["year"]
}
}
)
+46
View File
@@ -0,0 +1,46 @@
import { tool } from "langchain"
import lunarLib from "lunar-javascript"
const { Lunar } = lunarLib
// 当年冬至在节气表中的 key 为英文(上一年冬至占用中文 key)
const EN_TERM_NAMES = { DONG_ZHI: "冬至" }
/**
* 年份节气列表工具
* 基于 lunar-javascript 计算给定年份的 24 节气精确日期
*/
export const getYearTermsTool = tool(
async ({ year }) => {
try {
const table = Lunar.fromYmd(year, 1, 1).getJieQiTable()
const terms = []
for (const [key, solar] of Object.entries(table)) {
// 只保留属于目标年份的节气(表首含上一年边界节气)
if (solar.getYear() !== year) continue
const name = EN_TERM_NAMES[key] ?? key
terms.push({ date: solar.toString(), name })
}
terms.sort((a, b) => a.date.localeCompare(b.date))
return JSON.stringify({ year, terms }, null, 2)
} catch (error) {
return JSON.stringify({ error: error.message }, null, 2)
}
},
{
name: "get_year_terms",
description: "查询给定年份节气所在日期列表",
schema: {
type: "object",
properties: {
year: {
type: "number",
description: "年份",
minimum: 1900,
maximum: 2100
}
},
required: ["year"]
}
}
)