@nhtio/adk 1.20260607.2 → 1.20260609.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +230 -0
- package/batteries/embeddings/openai/adapter.cjs +1 -1
- package/batteries/embeddings/openai/adapter.mjs +1 -1
- package/batteries/embeddings/openai/exceptions.cjs +1 -1
- package/batteries/embeddings/openai/exceptions.mjs +1 -1
- package/batteries/embeddings/openai/types.d.ts +7 -0
- package/batteries/embeddings/webllm/adapter.cjs +1 -1
- package/batteries/embeddings/webllm/adapter.mjs +1 -1
- package/batteries/embeddings/webllm/exceptions.cjs +1 -1
- package/batteries/embeddings/webllm/exceptions.mjs +1 -1
- package/batteries/llm/chat_common/helpers.d.ts +165 -0
- package/batteries/llm/chat_common/types.d.ts +309 -0
- package/batteries/llm/index.d.ts +5 -0
- package/batteries/llm/ollama/adapter.cjs +736 -0
- package/batteries/llm/ollama/adapter.cjs.map +1 -0
- package/batteries/llm/ollama/adapter.d.ts +64 -0
- package/batteries/llm/ollama/adapter.mjs +734 -0
- package/batteries/llm/ollama/adapter.mjs.map +1 -0
- package/batteries/llm/ollama/exceptions.cjs +105 -0
- package/batteries/llm/ollama/exceptions.cjs.map +1 -0
- package/batteries/llm/ollama/exceptions.d.ts +112 -0
- package/batteries/llm/ollama/exceptions.mjs +96 -0
- package/batteries/llm/ollama/exceptions.mjs.map +1 -0
- package/batteries/llm/ollama/helpers.cjs +487 -0
- package/batteries/llm/ollama/helpers.cjs.map +1 -0
- package/batteries/llm/ollama/helpers.d.ts +158 -0
- package/batteries/llm/ollama/helpers.mjs +450 -0
- package/batteries/llm/ollama/helpers.mjs.map +1 -0
- package/batteries/llm/ollama/index.d.ts +29 -0
- package/batteries/llm/ollama/types.cjs +2 -0
- package/batteries/llm/ollama/types.d.ts +334 -0
- package/batteries/llm/ollama/types.mjs +0 -0
- package/batteries/llm/ollama/validation.cjs +130 -0
- package/batteries/llm/ollama/validation.cjs.map +1 -0
- package/batteries/llm/ollama/validation.d.ts +31 -0
- package/batteries/llm/ollama/validation.mjs +127 -0
- package/batteries/llm/ollama/validation.mjs.map +1 -0
- package/batteries/llm/ollama.cjs +54 -0
- package/batteries/llm/ollama.mjs +6 -0
- package/batteries/llm/openai_chat_completions/adapter.cjs +36 -19
- package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/adapter.mjs +23 -6
- package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/exceptions.cjs +1 -1
- package/batteries/llm/openai_chat_completions/exceptions.mjs +1 -1
- package/batteries/llm/openai_chat_completions/helpers.cjs +80 -320
- package/batteries/llm/openai_chat_completions/helpers.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/helpers.d.ts +68 -144
- package/batteries/llm/openai_chat_completions/helpers.mjs +40 -280
- package/batteries/llm/openai_chat_completions/helpers.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/types.d.ts +273 -181
- package/batteries/llm/openai_chat_completions/validation.cjs +2 -2
- package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/validation.mjs +2 -2
- package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions.cjs +29 -28
- package/batteries/llm/openai_chat_completions.mjs +2 -1
- package/batteries/llm/webllm_chat_completions/adapter.cjs +38 -19
- package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.d.ts +18 -0
- package/batteries/llm/webllm_chat_completions/adapter.mjs +25 -6
- package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/exceptions.cjs +1 -1
- package/batteries/llm/webllm_chat_completions/exceptions.mjs +1 -1
- package/batteries/llm/webllm_chat_completions/helpers.cjs +29 -28
- package/batteries/llm/webllm_chat_completions/helpers.mjs +2 -1
- package/batteries/llm/webllm_chat_completions/types.d.ts +21 -0
- package/batteries/llm/webllm_chat_completions/validation.cjs +13 -1
- package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/validation.d.ts +12 -0
- package/batteries/llm/webllm_chat_completions/validation.mjs +13 -1
- package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions.cjs +29 -28
- package/batteries/llm/webllm_chat_completions.mjs +2 -1
- package/batteries/llm.cjs +44 -28
- package/batteries/llm.mjs +9 -4
- package/batteries/storage/flydrive.cjs +1 -1
- package/batteries/storage/flydrive.mjs +1 -1
- package/batteries/storage/in_memory/index.d.ts +1 -1
- package/batteries/storage/in_memory.cjs +2 -2
- package/batteries/storage/in_memory.cjs.map +1 -1
- package/batteries/storage/in_memory.mjs +2 -2
- package/batteries/storage/in_memory.mjs.map +1 -1
- package/batteries/storage/opfs/index.d.ts +19 -0
- package/batteries/storage/opfs.cjs +1 -1
- package/batteries/storage/opfs.cjs.map +1 -1
- package/batteries/storage/opfs.mjs +1 -1
- package/batteries/storage/opfs.mjs.map +1 -1
- package/batteries/tools/_shared/index.d.ts +121 -0
- package/batteries/tools/_shared.cjs +157 -0
- package/batteries/tools/_shared.cjs.map +1 -0
- package/batteries/tools/_shared.mjs +149 -0
- package/batteries/tools/_shared.mjs.map +1 -0
- package/batteries/tools/color.cjs +3 -2
- package/batteries/tools/color.cjs.map +1 -1
- package/batteries/tools/color.mjs +3 -2
- package/batteries/tools/color.mjs.map +1 -1
- package/batteries/tools/comparison.cjs +4 -3
- package/batteries/tools/comparison.cjs.map +1 -1
- package/batteries/tools/comparison.mjs +4 -3
- package/batteries/tools/comparison.mjs.map +1 -1
- package/batteries/tools/data_structure.cjs +30 -10
- package/batteries/tools/data_structure.cjs.map +1 -1
- package/batteries/tools/data_structure.mjs +30 -10
- package/batteries/tools/data_structure.mjs.map +1 -1
- package/batteries/tools/datetime_extended.cjs +5 -10
- package/batteries/tools/datetime_extended.cjs.map +1 -1
- package/batteries/tools/datetime_extended.mjs +5 -10
- package/batteries/tools/datetime_extended.mjs.map +1 -1
- package/batteries/tools/datetime_math.cjs +2 -2
- package/batteries/tools/datetime_math.mjs +2 -2
- package/batteries/tools/encoding.cjs +13 -4
- package/batteries/tools/encoding.cjs.map +1 -1
- package/batteries/tools/encoding.mjs +13 -4
- package/batteries/tools/encoding.mjs.map +1 -1
- package/batteries/tools/formatting.cjs +4 -4
- package/batteries/tools/formatting.cjs.map +1 -1
- package/batteries/tools/formatting.mjs +4 -4
- package/batteries/tools/formatting.mjs.map +1 -1
- package/batteries/tools/geo_basics.cjs +2 -2
- package/batteries/tools/geo_basics.mjs +2 -2
- package/batteries/tools/index.d.ts +3 -0
- package/batteries/tools/math.cjs +10 -8
- package/batteries/tools/math.cjs.map +1 -1
- package/batteries/tools/math.mjs +10 -8
- package/batteries/tools/math.mjs.map +1 -1
- package/batteries/tools/memory.cjs +5 -5
- package/batteries/tools/memory.mjs +5 -5
- package/batteries/tools/parsing.cjs +9 -5
- package/batteries/tools/parsing.cjs.map +1 -1
- package/batteries/tools/parsing.mjs +9 -5
- package/batteries/tools/parsing.mjs.map +1 -1
- package/batteries/tools/retrievables.cjs +4 -4
- package/batteries/tools/retrievables.mjs +4 -4
- package/batteries/tools/scrapper/exceptions.d.ts +21 -0
- package/batteries/tools/scrapper/index.d.ts +172 -0
- package/batteries/tools/scrapper/shared.d.ts +139 -0
- package/batteries/tools/scrapper.cjs +8 -0
- package/batteries/tools/scrapper.mjs +2 -0
- package/batteries/tools/searxng/exceptions.d.ts +21 -0
- package/batteries/tools/searxng/index.d.ts +177 -0
- package/batteries/tools/searxng.cjs +6 -0
- package/batteries/tools/searxng.mjs +2 -0
- package/batteries/tools/standing_instructions.cjs +4 -4
- package/batteries/tools/standing_instructions.mjs +4 -4
- package/batteries/tools/statistics.cjs +54 -43
- package/batteries/tools/statistics.cjs.map +1 -1
- package/batteries/tools/statistics.mjs +54 -43
- package/batteries/tools/statistics.mjs.map +1 -1
- package/batteries/tools/string_processing.cjs +5 -5
- package/batteries/tools/string_processing.cjs.map +1 -1
- package/batteries/tools/string_processing.mjs +5 -5
- package/batteries/tools/string_processing.mjs.map +1 -1
- package/batteries/tools/structured_data.cjs +8 -13
- package/batteries/tools/structured_data.cjs.map +1 -1
- package/batteries/tools/structured_data.mjs +8 -13
- package/batteries/tools/structured_data.mjs.map +1 -1
- package/batteries/tools/text_analysis.cjs +3 -3
- package/batteries/tools/text_analysis.mjs +3 -3
- package/batteries/tools/text_comparison.cjs +2 -2
- package/batteries/tools/text_comparison.mjs +2 -2
- package/batteries/tools/time.cjs +2 -2
- package/batteries/tools/time.mjs +2 -2
- package/batteries/tools/unit_conversion.cjs +10 -8
- package/batteries/tools/unit_conversion.cjs.map +1 -1
- package/batteries/tools/unit_conversion.mjs +10 -8
- package/batteries/tools/unit_conversion.mjs.map +1 -1
- package/batteries/tools/web_retrieval/index.d.ts +186 -0
- package/batteries/tools/web_retrieval.cjs +206 -0
- package/batteries/tools/web_retrieval.cjs.map +1 -0
- package/batteries/tools/web_retrieval.mjs +201 -0
- package/batteries/tools/web_retrieval.mjs.map +1 -0
- package/batteries/tools.cjs +15 -0
- package/batteries/tools.mjs +4 -1
- package/batteries/vector/arangodb/index.d.ts +2 -0
- package/batteries/vector/arangodb.cjs +2 -1
- package/batteries/vector/arangodb.cjs.map +1 -1
- package/batteries/vector/arangodb.mjs +2 -1
- package/batteries/vector/arangodb.mjs.map +1 -1
- package/batteries/vector/builder.cjs +31 -0
- package/batteries/vector/builder.cjs.map +1 -1
- package/batteries/vector/builder.d.ts +58 -0
- package/batteries/vector/builder.mjs +31 -0
- package/batteries/vector/builder.mjs.map +1 -1
- package/batteries/vector/chroma/index.d.ts +4 -0
- package/batteries/vector/chroma.cjs +3 -0
- package/batteries/vector/chroma.cjs.map +1 -1
- package/batteries/vector/chroma.mjs +3 -0
- package/batteries/vector/chroma.mjs.map +1 -1
- package/batteries/vector/clickhouse/index.d.ts +2 -0
- package/batteries/vector/clickhouse.cjs +2 -1
- package/batteries/vector/clickhouse.cjs.map +1 -1
- package/batteries/vector/clickhouse.mjs +2 -1
- package/batteries/vector/clickhouse.mjs.map +1 -1
- package/batteries/vector/cloudflare/index.d.ts +2 -0
- package/batteries/vector/cloudflare.cjs +2 -1
- package/batteries/vector/cloudflare.cjs.map +1 -1
- package/batteries/vector/cloudflare.mjs +2 -1
- package/batteries/vector/cloudflare.mjs.map +1 -1
- package/batteries/vector/conformance/index.d.ts +22 -0
- package/batteries/vector/conformance.cjs +22 -0
- package/batteries/vector/conformance.cjs.map +1 -1
- package/batteries/vector/conformance.mjs +22 -0
- package/batteries/vector/conformance.mjs.map +1 -1
- package/batteries/vector/contract.cjs +22 -0
- package/batteries/vector/contract.cjs.map +1 -1
- package/batteries/vector/contract.d.ts +51 -0
- package/batteries/vector/contract.mjs +22 -0
- package/batteries/vector/contract.mjs.map +1 -1
- package/batteries/vector/couchbase/index.d.ts +2 -0
- package/batteries/vector/couchbase.cjs +2 -1
- package/batteries/vector/couchbase.cjs.map +1 -1
- package/batteries/vector/couchbase.mjs +2 -1
- package/batteries/vector/couchbase.mjs.map +1 -1
- package/batteries/vector/duckdb/index.d.ts +2 -0
- package/batteries/vector/duckdb.cjs +2 -1
- package/batteries/vector/duckdb.cjs.map +1 -1
- package/batteries/vector/duckdb.mjs +2 -1
- package/batteries/vector/duckdb.mjs.map +1 -1
- package/batteries/vector/elasticsearch/index.d.ts +2 -0
- package/batteries/vector/elasticsearch.cjs +2 -1
- package/batteries/vector/elasticsearch.cjs.map +1 -1
- package/batteries/vector/elasticsearch.mjs +2 -1
- package/batteries/vector/elasticsearch.mjs.map +1 -1
- package/batteries/vector/exceptions.cjs +1 -1
- package/batteries/vector/exceptions.mjs +1 -1
- package/batteries/vector/factory.cjs +6 -0
- package/batteries/vector/factory.cjs.map +1 -1
- package/batteries/vector/factory.d.ts +14 -0
- package/batteries/vector/factory.mjs +6 -0
- package/batteries/vector/factory.mjs.map +1 -1
- package/batteries/vector/filters.cjs +22 -1
- package/batteries/vector/filters.cjs.map +1 -1
- package/batteries/vector/filters.d.ts +38 -0
- package/batteries/vector/filters.mjs +22 -1
- package/batteries/vector/filters.mjs.map +1 -1
- package/batteries/vector/helpers.cjs +13 -0
- package/batteries/vector/helpers.cjs.map +1 -1
- package/batteries/vector/helpers.d.ts +14 -0
- package/batteries/vector/helpers.mjs +13 -0
- package/batteries/vector/helpers.mjs.map +1 -1
- package/batteries/vector/hnswlib/index.d.ts +2 -0
- package/batteries/vector/hnswlib.cjs +2 -1
- package/batteries/vector/hnswlib.cjs.map +1 -1
- package/batteries/vector/hnswlib.mjs +2 -1
- package/batteries/vector/hnswlib.mjs.map +1 -1
- package/batteries/vector/in_memory/index.d.ts +1 -0
- package/batteries/vector/in_memory.cjs +1 -0
- package/batteries/vector/in_memory.cjs.map +1 -1
- package/batteries/vector/in_memory.mjs +1 -0
- package/batteries/vector/in_memory.mjs.map +1 -1
- package/batteries/vector/lancedb/index.d.ts +2 -0
- package/batteries/vector/lancedb.cjs +2 -1
- package/batteries/vector/lancedb.cjs.map +1 -1
- package/batteries/vector/lancedb.mjs +2 -1
- package/batteries/vector/lancedb.mjs.map +1 -1
- package/batteries/vector/mariadb/index.d.ts +2 -0
- package/batteries/vector/mariadb.cjs +2 -1
- package/batteries/vector/mariadb.cjs.map +1 -1
- package/batteries/vector/mariadb.mjs +2 -1
- package/batteries/vector/mariadb.mjs.map +1 -1
- package/batteries/vector/meilisearch/index.d.ts +2 -0
- package/batteries/vector/meilisearch.cjs +2 -1
- package/batteries/vector/meilisearch.cjs.map +1 -1
- package/batteries/vector/meilisearch.mjs +2 -1
- package/batteries/vector/meilisearch.mjs.map +1 -1
- package/batteries/vector/migrate.cjs +18 -1
- package/batteries/vector/migrate.cjs.map +1 -1
- package/batteries/vector/migrate.d.ts +31 -0
- package/batteries/vector/migrate.mjs +18 -1
- package/batteries/vector/migrate.mjs.map +1 -1
- package/batteries/vector/milvus/index.d.ts +5 -0
- package/batteries/vector/milvus.cjs +4 -0
- package/batteries/vector/milvus.cjs.map +1 -1
- package/batteries/vector/milvus.mjs +4 -0
- package/batteries/vector/milvus.mjs.map +1 -1
- package/batteries/vector/mongodb/index.d.ts +2 -0
- package/batteries/vector/mongodb.cjs +2 -1
- package/batteries/vector/mongodb.cjs.map +1 -1
- package/batteries/vector/mongodb.mjs +2 -1
- package/batteries/vector/mongodb.mjs.map +1 -1
- package/batteries/vector/neo4j/index.d.ts +2 -0
- package/batteries/vector/neo4j.cjs +2 -1
- package/batteries/vector/neo4j.cjs.map +1 -1
- package/batteries/vector/neo4j.mjs +2 -1
- package/batteries/vector/neo4j.mjs.map +1 -1
- package/batteries/vector/opensearch/index.d.ts +2 -0
- package/batteries/vector/opensearch.cjs +2 -1
- package/batteries/vector/opensearch.cjs.map +1 -1
- package/batteries/vector/opensearch.mjs +2 -1
- package/batteries/vector/opensearch.mjs.map +1 -1
- package/batteries/vector/oracle23ai/index.d.ts +2 -0
- package/batteries/vector/oracle23ai.cjs +2 -1
- package/batteries/vector/oracle23ai.cjs.map +1 -1
- package/batteries/vector/oracle23ai.mjs +2 -1
- package/batteries/vector/oracle23ai.mjs.map +1 -1
- package/batteries/vector/orama/index.d.ts +1 -0
- package/batteries/vector/orama.cjs +1 -0
- package/batteries/vector/orama.cjs.map +1 -1
- package/batteries/vector/orama.mjs +1 -0
- package/batteries/vector/orama.mjs.map +1 -1
- package/batteries/vector/pgvector/index.d.ts +9 -2
- package/batteries/vector/pgvector.cjs +4 -0
- package/batteries/vector/pgvector.cjs.map +1 -1
- package/batteries/vector/pgvector.mjs +4 -0
- package/batteries/vector/pgvector.mjs.map +1 -1
- package/batteries/vector/pinecone/index.d.ts +5 -0
- package/batteries/vector/pinecone.cjs +3 -1
- package/batteries/vector/pinecone.cjs.map +1 -1
- package/batteries/vector/pinecone.mjs +3 -1
- package/batteries/vector/pinecone.mjs.map +1 -1
- package/batteries/vector/plan.d.ts +27 -0
- package/batteries/vector/qdrant/index.d.ts +5 -0
- package/batteries/vector/qdrant.cjs +4 -0
- package/batteries/vector/qdrant.cjs.map +1 -1
- package/batteries/vector/qdrant.mjs +4 -0
- package/batteries/vector/qdrant.mjs.map +1 -1
- package/batteries/vector/redis/index.d.ts +2 -0
- package/batteries/vector/redis.cjs +2 -1
- package/batteries/vector/redis.cjs.map +1 -1
- package/batteries/vector/redis.mjs +2 -1
- package/batteries/vector/redis.mjs.map +1 -1
- package/batteries/vector/retrievable.cjs +9 -1
- package/batteries/vector/retrievable.cjs.map +1 -1
- package/batteries/vector/retrievable.mjs +9 -1
- package/batteries/vector/retrievable.mjs.map +1 -1
- package/batteries/vector/retrievable_glue.d.ts +21 -0
- package/batteries/vector/s3vectors/index.d.ts +2 -0
- package/batteries/vector/s3vectors.cjs +2 -1
- package/batteries/vector/s3vectors.cjs.map +1 -1
- package/batteries/vector/s3vectors.mjs +2 -1
- package/batteries/vector/s3vectors.mjs.map +1 -1
- package/batteries/vector/schema.cjs +28 -0
- package/batteries/vector/schema.cjs.map +1 -1
- package/batteries/vector/schema.d.ts +39 -0
- package/batteries/vector/schema.mjs +28 -0
- package/batteries/vector/schema.mjs.map +1 -1
- package/batteries/vector/solr/index.d.ts +2 -0
- package/batteries/vector/solr.cjs +2 -1
- package/batteries/vector/solr.cjs.map +1 -1
- package/batteries/vector/solr.mjs +2 -1
- package/batteries/vector/solr.mjs.map +1 -1
- package/batteries/vector/sqlite_vec/index.d.ts +6 -3
- package/batteries/vector/sqlite_vec.cjs +2 -0
- package/batteries/vector/sqlite_vec.cjs.map +1 -1
- package/batteries/vector/sqlite_vec.mjs +2 -0
- package/batteries/vector/sqlite_vec.mjs.map +1 -1
- package/batteries/vector/surrealdb/index.d.ts +2 -0
- package/batteries/vector/surrealdb.cjs +2 -1
- package/batteries/vector/surrealdb.cjs.map +1 -1
- package/batteries/vector/surrealdb.mjs +2 -1
- package/batteries/vector/surrealdb.mjs.map +1 -1
- package/batteries/vector/types.d.ts +27 -0
- package/batteries/vector/typesense/index.d.ts +2 -0
- package/batteries/vector/typesense.cjs +2 -1
- package/batteries/vector/typesense.cjs.map +1 -1
- package/batteries/vector/typesense.mjs +2 -1
- package/batteries/vector/typesense.mjs.map +1 -1
- package/batteries/vector/validation.cjs +14 -0
- package/batteries/vector/validation.cjs.map +1 -1
- package/batteries/vector/validation.d.ts +14 -0
- package/batteries/vector/validation.mjs +14 -0
- package/batteries/vector/validation.mjs.map +1 -1
- package/batteries/vector/vector_store_constructor.cjs +1 -1
- package/batteries/vector/vector_store_constructor.cjs.map +1 -1
- package/batteries/vector/vector_store_constructor.d.ts +1 -1
- package/batteries/vector/vector_store_constructor.mjs +1 -1
- package/batteries/vector/vector_store_constructor.mjs.map +1 -1
- package/batteries/vector/vespa/index.d.ts +2 -0
- package/batteries/vector/vespa.cjs +2 -1
- package/batteries/vector/vespa.cjs.map +1 -1
- package/batteries/vector/vespa.mjs +2 -1
- package/batteries/vector/vespa.mjs.map +1 -1
- package/batteries/vector/weaviate/index.d.ts +2 -0
- package/batteries/vector/weaviate.cjs +2 -1
- package/batteries/vector/weaviate.cjs.map +1 -1
- package/batteries/vector/weaviate.mjs +2 -1
- package/batteries/vector/weaviate.mjs.map +1 -1
- package/batteries.cjs +58 -28
- package/batteries.mjs +12 -5
- package/{common-BT0nfCi9.mjs → common-DYDUi99O.mjs} +9 -9
- package/common-DYDUi99O.mjs.map +1 -0
- package/{common-Cj8TaQ9U.js → common-DZl3ADJs.js} +9 -9
- package/common-DZl3ADJs.js.map +1 -0
- package/common.cjs +7 -7
- package/common.mjs +7 -7
- package/{dispatch_runner-DPcS7Y_M.mjs → dispatch_runner--ZhdDWRZ.mjs} +27 -5
- package/{dispatch_runner-DPcS7Y_M.mjs.map → dispatch_runner--ZhdDWRZ.mjs.map} +1 -1
- package/{dispatch_runner-BHBNupqp.js → dispatch_runner-nHDKkxye.js} +27 -5
- package/{dispatch_runner-BHBNupqp.js.map → dispatch_runner-nHDKkxye.js.map} +1 -1
- package/dispatch_runner.cjs +1 -1
- package/dispatch_runner.d.ts +1 -1
- package/dispatch_runner.mjs +1 -1
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.cjs +1 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.cjs.map +1 -1
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.d.ts +1 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.mjs +1 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.mjs.map +1 -1
- package/eslint/rules/no_model_in_tool_handler.cjs +1 -0
- package/eslint/rules/no_model_in_tool_handler.cjs.map +1 -1
- package/eslint/rules/no_model_in_tool_handler.d.ts +1 -0
- package/eslint/rules/no_model_in_tool_handler.mjs +1 -0
- package/eslint/rules/no_model_in_tool_handler.mjs.map +1 -1
- package/eslint/rules/require_validator_any_required.cjs +1 -0
- package/eslint/rules/require_validator_any_required.cjs.map +1 -1
- package/eslint/rules/require_validator_any_required.d.ts +1 -0
- package/eslint/rules/require_validator_any_required.mjs +1 -0
- package/eslint/rules/require_validator_any_required.mjs.map +1 -1
- package/eslint/rules/thought_payload_requires_replay_tag.cjs +1 -0
- package/eslint/rules/thought_payload_requires_replay_tag.cjs.map +1 -1
- package/eslint/rules/thought_payload_requires_replay_tag.d.ts +1 -0
- package/eslint/rules/thought_payload_requires_replay_tag.mjs +1 -0
- package/eslint/rules/thought_payload_requires_replay_tag.mjs.map +1 -1
- package/eslint/rules/token_encoding_requires_context_window.cjs +1 -0
- package/eslint/rules/token_encoding_requires_context_window.cjs.map +1 -1
- package/eslint/rules/token_encoding_requires_context_window.d.ts +1 -0
- package/eslint/rules/token_encoding_requires_context_window.mjs +1 -0
- package/eslint/rules/token_encoding_requires_context_window.mjs.map +1 -1
- package/eslint/rules.cjs +1 -1
- package/eslint/rules.mjs +1 -1
- package/eslint.cjs +2 -2
- package/eslint.mjs +2 -2
- package/{exceptions-BeWH2FwP.mjs → exceptions-BDhN0Xzr.mjs} +3 -2
- package/exceptions-BDhN0Xzr.mjs.map +1 -0
- package/{exceptions-CitH5wZI.js → exceptions-BRXrUKiW.js} +3 -2
- package/exceptions-BRXrUKiW.js.map +1 -0
- package/exceptions.cjs +2 -2
- package/exceptions.mjs +2 -2
- package/factories.cjs +1 -1
- package/factories.mjs +1 -1
- package/forge.cjs +4 -4
- package/forge.d.ts +1 -1
- package/forge.mjs +4 -4
- package/guards.cjs +9 -9
- package/guards.mjs +9 -9
- package/helpers-DSTFxTiC.js +497 -0
- package/helpers-DSTFxTiC.js.map +1 -0
- package/helpers-xhrQbMAG.mjs +306 -0
- package/helpers-xhrQbMAG.mjs.map +1 -0
- package/index.cjs +12 -12
- package/index.mjs +12 -12
- package/lib/classes/base_exception.d.ts +1 -0
- package/lib/classes/media.d.ts +10 -0
- package/lib/classes/retrievable.d.ts +1 -1
- package/lib/classes/spooled_json_artifact.d.ts +1 -1
- package/lib/classes/spooled_markdown_artifact.d.ts +1 -0
- package/lib/classes/tokenizable.d.ts +3 -0
- package/lib/classes/tool.d.ts +8 -0
- package/lib/classes/turn_gate.d.ts +6 -0
- package/lib/dispatch_runner.d.ts +4 -32
- package/lib/helpers/bignum.cjs +82 -0
- package/lib/helpers/bignum.cjs.map +1 -0
- package/lib/helpers/bignum.d.ts +52 -0
- package/lib/helpers/bignum.mjs +74 -0
- package/lib/helpers/bignum.mjs.map +1 -0
- package/lib/turn_runner.d.ts +1 -1
- package/lib/types/dispatch_runner.d.ts +83 -0
- package/lib/utils/exceptions.d.ts +1 -1
- package/lib/utils/retry.cjs.map +1 -1
- package/lib/utils/retry.d.ts +2 -0
- package/lib/utils/retry.mjs.map +1 -1
- package/mcp/adk-docs-corpus.json +1 -1
- package/package.json +259 -204
- package/{runtime-j92CNi5z.mjs → runtime-Bz5zA8wc.mjs} +2 -2
- package/{runtime-j92CNi5z.mjs.map → runtime-Bz5zA8wc.mjs.map} +1 -1
- package/{runtime-MFFcJrRv.js → runtime-DslE1aBw.js} +2 -2
- package/{runtime-MFFcJrRv.js.map → runtime-DslE1aBw.js.map} +1 -1
- package/scrapper-BHM1mCde.mjs +432 -0
- package/scrapper-BHM1mCde.mjs.map +1 -0
- package/scrapper-BeweWurk.js +462 -0
- package/scrapper-BeweWurk.js.map +1 -0
- package/searxng-BJFulNcK.mjs +247 -0
- package/searxng-BJFulNcK.mjs.map +1 -0
- package/searxng-B_D--V5q.js +265 -0
- package/searxng-B_D--V5q.js.map +1 -0
- package/skills/adk-assembly/SKILL.md +2 -2
- package/{spooled_artifact-CHoZgWwI.mjs → spooled_artifact-7eePq7JA.mjs} +5 -5
- package/{spooled_artifact-CHoZgWwI.mjs.map → spooled_artifact-7eePq7JA.mjs.map} +1 -1
- package/{spooled_artifact-BTq6Nzfy.js → spooled_artifact-DX8LLyUX.js} +5 -5
- package/{spooled_artifact-BTq6Nzfy.js.map → spooled_artifact-DX8LLyUX.js.map} +1 -1
- package/spooled_artifact.cjs +2 -2
- package/spooled_artifact.mjs +2 -2
- package/{spooled_markdown_artifact-CALSDxIx.js → spooled_markdown_artifact-ClX72lek.js} +4 -4
- package/spooled_markdown_artifact-ClX72lek.js.map +1 -0
- package/{spooled_markdown_artifact-Ci5UL7l4.mjs → spooled_markdown_artifact-wkrBF3oX.mjs} +4 -4
- package/spooled_markdown_artifact-wkrBF3oX.mjs.map +1 -0
- package/{thought-D34QQZZ9.mjs → thought-B_vxAiKU.mjs} +5 -5
- package/{thought-D34QQZZ9.mjs.map → thought-B_vxAiKU.mjs.map} +1 -1
- package/{thought-BbwhJ1wb.js → thought-DLwpF7MI.js} +5 -5
- package/{thought-BbwhJ1wb.js.map → thought-DLwpF7MI.js.map} +1 -1
- package/{tool-CVyZkFC7.js → tool-D5WGVIcI.js} +4 -4
- package/{tool-CVyZkFC7.js.map → tool-D5WGVIcI.js.map} +1 -1
- package/{tool-CMhaDRNd.mjs → tool-wMYMVl60.mjs} +4 -4
- package/{tool-CMhaDRNd.mjs.map → tool-wMYMVl60.mjs.map} +1 -1
- package/{tool_call-CV5qVNlb.mjs → tool_call-B4-_-vjG.mjs} +5 -5
- package/tool_call-B4-_-vjG.mjs.map +1 -0
- package/{tool_call-Db68hB7y.js → tool_call-DixVlW40.js} +5 -5
- package/tool_call-DixVlW40.js.map +1 -0
- package/{tool_registry-D1pSSlsd.mjs → tool_registry-791Vrjtf.mjs} +4 -3
- package/tool_registry-791Vrjtf.mjs.map +1 -0
- package/{tool_registry-DYUYqXvo.js → tool_registry-CKJPze3j.js} +4 -3
- package/tool_registry-CKJPze3j.js.map +1 -0
- package/{turn_runner-DqWHNP80.js → turn_runner-HXImLGIn.js} +7 -7
- package/turn_runner-HXImLGIn.js.map +1 -0
- package/{turn_runner-fg1Wc3dK.mjs → turn_runner-ZyYO-Kti.mjs} +7 -7
- package/turn_runner-ZyYO-Kti.mjs.map +1 -0
- package/turn_runner.cjs +1 -1
- package/turn_runner.mjs +1 -1
- package/types.d.ts +1 -1
- package/common-BT0nfCi9.mjs.map +0 -1
- package/common-Cj8TaQ9U.js.map +0 -1
- package/exceptions-BeWH2FwP.mjs.map +0 -1
- package/exceptions-CitH5wZI.js.map +0 -1
- package/spooled_markdown_artifact-CALSDxIx.js.map +0 -1
- package/spooled_markdown_artifact-Ci5UL7l4.mjs.map +0 -1
- package/tool_call-CV5qVNlb.mjs.map +0 -1
- package/tool_call-Db68hB7y.js.map +0 -1
- package/tool_registry-D1pSSlsd.mjs.map +0 -1
- package/tool_registry-DYUYqXvo.js.map +0 -1
- package/turn_runner-DqWHNP80.js.map +0 -1
- package/turn_runner-fg1Wc3dK.mjs.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Ble4zEEl.js");
|
|
3
|
-
const require_tool = require("../../tool-
|
|
4
|
-
require("../../common-
|
|
3
|
+
const require_tool = require("../../tool-D5WGVIcI.js");
|
|
4
|
+
require("../../common-DZl3ADJs.js");
|
|
5
5
|
let _nhtio_validation = require("@nhtio/validation");
|
|
6
6
|
let luxon = require("luxon");
|
|
7
7
|
let chrono_node = require("chrono-node");
|
|
@@ -235,14 +235,9 @@ var datePeriodTool = new require_tool.Tool({
|
|
|
235
235
|
result = boundary === "start" ? dt.startOf("month") : dt.endOf("month");
|
|
236
236
|
break;
|
|
237
237
|
case "quarter": {
|
|
238
|
-
const
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
month: qStartMonth,
|
|
242
|
-
day: 1
|
|
243
|
-
}).startOf("day");
|
|
244
|
-
const adjusted = qStart > dt ? qStart.minus({ months: 3 }) : qStart;
|
|
245
|
-
result = boundary === "start" ? adjusted : adjusted.plus({ months: 3 }).minus({ days: 1 }).endOf("day");
|
|
238
|
+
const monthsIntoQuarter = (dt.month - fyStart + 12) % 12 % 3;
|
|
239
|
+
const qStart = dt.startOf("month").minus({ months: monthsIntoQuarter });
|
|
240
|
+
result = boundary === "start" ? qStart : qStart.plus({ months: 3 }).minus({ days: 1 }).endOf("day");
|
|
246
241
|
break;
|
|
247
242
|
}
|
|
248
243
|
case "year":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datetime_extended.cjs","names":[],"sources":["../../../src/batteries/tools/datetime_extended/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for parsing natural-language dates and business-calendar calculations.\n *\n * @module @nhtio/adk/batteries/tools/datetime_extended\n *\n * @remarks\n * Pre-constructed bundled tools for the `datetime_extended` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport * as chrono from 'chrono-node'\nimport { Tool } from '@nhtio/adk/common'\nimport { DateTime, IANAZone } from 'luxon'\nimport { validator } from '@nhtio/validation'\n\nfunction resolveZone(timezone: string | undefined): { zone: string; error?: string } {\n if (!timezone) return { zone: 'UTC' }\n if (!IANAZone.isValidZone(timezone)) return { zone: '', error: `Invalid timezone \"${timezone}\".` }\n return { zone: timezone }\n}\n\nfunction countBusinessDays(from: DateTime, to: DateTime): number {\n const forward = to >= from\n const start = forward ? from.startOf('day') : to.startOf('day')\n const end = forward ? to.startOf('day') : from.startOf('day')\n\n const totalDays = Math.round(end.diff(start, 'days').days)\n const fullWeeks = Math.floor(totalDays / 7)\n let bdays = fullWeeks * 5\n\n let cursor = start.plus({ days: fullWeeks * 7 })\n while (cursor < end) {\n cursor = cursor.plus({ days: 1 })\n if (cursor.weekday <= 5) bdays++\n }\n\n return forward ? bdays : -bdays\n}\n\n/**\n * Find the Nth occurrence of a weekday in a given month.\n *\n * @remarks\n * Examples: \"2nd Friday of March 2026\", \"last Monday of January 2025\". Accepts 1st–5th and\n * `last`. Returns an error if the month does not contain that many occurrences of the weekday.\n */\nexport const dateNthWeekdayTool = new Tool({\n name: 'date_nth_weekday',\n description:\n 'Find the Nth occurrence of a weekday in a given month (e.g., \"2nd Friday of March 2026\", \"last Monday of next month\"). Supports 1st–5th and \"last\".',\n inputSchema: validator.object({\n nth: validator\n .string()\n .required()\n .description('Which occurrence: \"1st\", \"2nd\", \"3rd\", \"4th\", \"5th\", or \"last\".'),\n weekday: validator\n .string()\n .valid('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday')\n .required()\n .description('Day of the week.'),\n month: validator.number().required().description('Month number (1–12).'),\n year: validator.number().optional().description('Year (defaults to current year).'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC).'),\n }),\n handler: async (args) => {\n const {\n nth,\n weekday,\n month: rawMonth,\n year: rawYear,\n timezone,\n } = args as {\n nth: string\n weekday: string\n month: number\n year?: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const weekdayNames: Record<string, number> = {\n monday: 1,\n tuesday: 2,\n wednesday: 3,\n thursday: 4,\n friday: 5,\n saturday: 6,\n sunday: 7,\n }\n\n const targetWeekday = weekdayNames[weekday.toLowerCase()]\n const month = Math.floor(rawMonth)\n if (month < 1 || month > 12) return `Error: Month must be 1–12, got ${rawMonth}.`\n\n const year = Math.floor(rawYear ?? DateTime.now().setZone(zone).year)\n const nthRaw = nth.toLowerCase().replace(/\\s/g, '')\n\n const firstOfMonth = DateTime.fromObject({ year, month, day: 1 }, { zone })\n if (!firstOfMonth.isValid) return `Error: Invalid date for ${year}-${month}.`\n\n const occurrences: DateTime[] = []\n let cursor = firstOfMonth\n while (cursor.weekday !== targetWeekday) {\n cursor = cursor.plus({ days: 1 })\n }\n while (cursor.month === month) {\n occurrences.push(cursor)\n cursor = cursor.plus({ weeks: 1 })\n }\n\n let result: DateTime | undefined\n\n if (nthRaw === 'last') {\n result = occurrences[occurrences.length - 1]\n } else {\n const nthMap: Record<string, number> = {\n '1st': 1,\n '1': 1,\n 'first': 1,\n '2nd': 2,\n '2': 2,\n 'second': 2,\n '3rd': 3,\n '3': 3,\n 'third': 3,\n '4th': 4,\n '4': 4,\n 'fourth': 4,\n '5th': 5,\n '5': 5,\n 'fifth': 5,\n }\n const n = nthMap[nthRaw]\n if (!n) return `Error: Invalid nth value \"${nth}\". Use 1st–5th or \"last\".`\n if (n > occurrences.length) {\n return `Error: There is no ${nth} ${weekday} in ${firstOfMonth.toFormat('LLLL yyyy')} (only ${occurrences.length} occurrence${occurrences.length !== 1 ? 's' : ''}).`\n }\n result = occurrences[n - 1]\n }\n\n if (!result) return 'Error: Could not compute the date.'\n\n return `${nth} ${weekday} of ${result.toFormat('LLLL yyyy')}: ${result.toISODate()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy')}`\n },\n})\n\n/**\n * Get calendar metadata for a date.\n *\n * @remarks\n * Reports ISO week number, day of year, calendar quarter, fiscal quarter/year (configurable via\n * `fiscal_year_start_month`), week of month, and whether the date is a weekend. Accepts ISO\n * dates, natural-language (\"next Tuesday\"), and `now`.\n */\nexport const dateCalendarInfoTool = new Tool({\n name: 'date_calendar_info',\n description:\n 'Get calendar metadata for a date: ISO week number, day of year, calendar quarter, fiscal quarter/year, week of month, and whether it is a weekend or weekday.',\n inputSchema: validator.object({\n date: validator\n .string()\n .required()\n .description('ISO 8601 date, natural language date, or \"now\".'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC).'),\n fiscal_year_start_month: validator\n .number()\n .default(1)\n .description('Month when fiscal year starts (1–12, default: 1 = calendar year).'),\n }),\n handler: async (args) => {\n const {\n date: dateStr,\n timezone,\n fiscal_year_start_month: rawFyStart,\n } = args as {\n date: string\n timezone?: string\n fiscal_year_start_month: number\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n let dt: DateTime\n\n if (dateStr.toLowerCase() === 'now') {\n dt = DateTime.now().setZone(zone)\n } else {\n dt = DateTime.fromISO(dateStr, { zone })\n if (!dt.isValid) {\n const parsed = chrono.parseDate(dateStr, new Date())\n if (!parsed) return `Error: Could not parse date \"${dateStr}\".`\n dt = DateTime.fromJSDate(parsed).setZone(zone)\n }\n }\n\n const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n const calendarQuarter = Math.ceil(dt.month / 3)\n\n const monthInFY = (dt.month - fyStart + 12) % 12\n const fiscalQuarter = Math.floor(monthInFY / 3) + 1\n const fiscalYear = dt.month >= fyStart ? dt.year : dt.year - 1\n\n const firstOfMonth = dt.startOf('month')\n const weekOfMonth = Math.ceil((dt.day + firstOfMonth.weekday - 1) / 7)\n\n const dayOfYear = Math.floor(dt.diff(dt.startOf('year'), 'days').days) + 1\n\n const isWeekend = dt.weekday >= 6\n\n const lines = [\n `Date: ${dt.toISODate()} (${dt.toFormat('cccc, LLLL d, yyyy')})`,\n '',\n `ISO week number: ${dt.weekNumber} (ISO year: ${dt.weekYear})`,\n `Day of year: ${dayOfYear} / ${dt.daysInYear}`,\n `Day of week: ${dt.weekday} (${dt.toFormat('cccc')})`,\n `Week of month: ${weekOfMonth}`,\n `Weekend: ${isWeekend ? 'Yes' : 'No'}`,\n '',\n `Calendar quarter: Q${calendarQuarter}`,\n `Fiscal quarter: FQ${fiscalQuarter} (FY${fiscalYear}${fyStart !== 1 ? `, starts month ${fyStart}` : ''})`,\n ]\n\n return lines.join('\\n')\n },\n})\n\n/**\n * Parse a date/time expression from natural language or common formats.\n *\n * @remarks\n * Examples: `\"next Monday\"`, `\"March 5th\"`, `\"in 2 weeks\"`, `\"yesterday\"`. Uses chrono-node for\n * relative parsing. `reference_date` overrides the \"now\" anchor.\n */\nexport const dateParseTool = new Tool({\n name: 'date_parse',\n description:\n 'Parse a date/time string from natural language or common formats (\"next Monday\", \"March 5th\", \"in 2 weeks\", \"yesterday\"). Returns an ISO 8601 date.',\n inputSchema: validator.object({\n text: validator\n .string()\n .required()\n .description('Date/time expression to parse (natural language or structured)'),\n reference_date: validator\n .string()\n .optional()\n .description('ISO date to treat as \"now\" for relative expressions (default: current time)'),\n timezone: validator\n .string()\n .optional()\n .description('IANA timezone for the result (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const {\n text,\n reference_date: referenceDate,\n timezone,\n } = args as {\n text: string\n reference_date?: string\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n let refDate = new Date()\n if (referenceDate) {\n refDate = new Date(referenceDate)\n if (Number.isNaN(refDate.getTime()))\n return `Error: Invalid reference_date \"${referenceDate}\".`\n }\n\n const parsed = chrono.parseDate(text, refDate)\n if (!parsed) return `Error: Could not parse a date from \"${text}\".`\n\n const dt = DateTime.fromJSDate(parsed).setZone(zone)\n return `ISO: ${dt.toISO()}\\nFormatted: ${dt.toFormat('cccc, LLLL d, yyyy h:mm a ZZZZ')}`\n },\n})\n\n/**\n * Get the start or end of a time period containing a given date.\n *\n * @remarks\n * Periods: `day`, `week`, `isoweek` (Monday-start), `month`, `quarter`, `year`. Quarter and year\n * honour `fiscal_year_start_month` for fiscal calendars (default: 1 = calendar year).\n */\nexport const datePeriodTool = new Tool({\n name: 'date_period',\n description:\n 'Get the start or end of a time period (day, week, month, quarter, year) containing a given date. Supports fiscal year offsets.',\n inputSchema: validator.object({\n date: validator.string().required().description('ISO 8601 date or \"now\"'),\n period: validator\n .string()\n .valid('day', 'week', 'isoweek', 'month', 'quarter', 'year')\n .required()\n .description('Time period (isoweek = Monday-start week)'),\n boundary: validator\n .string()\n .valid('start', 'end')\n .required()\n .description('\"start\" for the first moment, \"end\" for the last moment of the period'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC)'),\n fiscal_year_start_month: validator\n .number()\n .default(1)\n .description(\n 'For quarter/year: month number when the fiscal year starts (1–12, default: 1 = calendar year)'\n ),\n }),\n handler: async (args) => {\n const {\n date: dateStr,\n period,\n boundary,\n timezone,\n fiscal_year_start_month: rawFyStart,\n } = args as {\n date: string\n period: 'day' | 'week' | 'isoweek' | 'month' | 'quarter' | 'year'\n boundary: 'start' | 'end'\n timezone?: string\n fiscal_year_start_month: number\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const dt =\n dateStr.toLowerCase() === 'now'\n ? DateTime.now().setZone(zone)\n : DateTime.fromISO(dateStr, { zone })\n if (!dt.isValid) return `Error: Invalid date \"${dateStr}\".`\n\n const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n let result: DateTime\n\n switch (period) {\n case 'day':\n result = boundary === 'start' ? dt.startOf('day') : dt.endOf('day')\n break\n case 'week':\n result = boundary === 'start' ? dt.startOf('week') : dt.endOf('week')\n break\n case 'isoweek':\n result =\n boundary === 'start'\n ? dt.startOf('week').set({ weekday: 1 })\n : dt.startOf('week').set({ weekday: 7 }).endOf('day')\n break\n case 'month':\n result = boundary === 'start' ? dt.startOf('month') : dt.endOf('month')\n break\n case 'quarter': {\n const monthInFY = (dt.month - fyStart + 12) % 12\n const qIndex = Math.floor(monthInFY / 3)\n const qStartMonth = ((qIndex * 3 + fyStart - 1) % 12) + 1\n const qStart = dt.set({ month: qStartMonth, day: 1 }).startOf('day')\n const adjusted = qStart > dt ? qStart.minus({ months: 3 }) : qStart\n result =\n boundary === 'start'\n ? adjusted\n : adjusted.plus({ months: 3 }).minus({ days: 1 }).endOf('day')\n break\n }\n case 'year':\n if (fyStart === 1) {\n result = boundary === 'start' ? dt.startOf('year') : dt.endOf('year')\n } else {\n const fyStartThis = dt.set({ month: fyStart, day: 1 }).startOf('day')\n const fyBase = dt >= fyStartThis ? fyStartThis : fyStartThis.minus({ years: 1 })\n result =\n boundary === 'start'\n ? fyBase\n : fyBase.plus({ years: 1 }).minus({ days: 1 }).endOf('day')\n }\n break\n }\n\n return `${boundary === 'start' ? 'Start' : 'End'} of ${period} containing ${dateStr}: ${result.toISO()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy h:mm:ss a ZZZZ')}`\n },\n})\n\n/**\n * Count business days between two dates, or compute the date N business days away.\n *\n * @remarks\n * Monday–Friday only; no holiday calendar awareness. Provide either `to` (count between) or\n * `add_days` (compute target date). Negative `add_days` walks backwards.\n */\nexport const dateBusinessDaysTool = new Tool({\n name: 'date_business_days',\n description:\n 'Count business days (Mon–Fri, no holiday awareness) between two dates, or calculate the date that is N business days from a start date.',\n inputSchema: validator.object({\n from: validator.string().required().description('Start date (ISO 8601 or \"now\")'),\n to: validator\n .string()\n .optional()\n .description('End date (ISO 8601 or \"now\") — for counting business days between two dates'),\n add_days: validator\n .number()\n .optional()\n .description('Instead of \"to\": number of business days to add (negative to subtract)'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const {\n from: fromStr,\n to: toStr,\n add_days: addDays,\n timezone,\n } = args as {\n from: string\n to?: string\n add_days?: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const fromDt = (\n fromStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(fromStr)\n ).setZone(zone)\n if (!fromDt.isValid) return `Error: Invalid from date \"${fromStr}\".`\n\n if (addDays !== undefined) {\n const n = Math.floor(addDays)\n let cursor = fromDt.startOf('day')\n let remaining = Math.abs(n)\n const dir = n >= 0 ? 1 : -1\n while (remaining > 0) {\n cursor = cursor.plus({ days: dir })\n if (cursor.weekday <= 5) remaining--\n }\n return `${n >= 0 ? '+' : ''}${n} business day${Math.abs(n) !== 1 ? 's' : ''} from ${fromStr}: ${cursor.toISODate()}\\nFormatted: ${cursor.toFormat('cccc, LLLL d, yyyy')}`\n }\n\n if (!toStr) return 'Error: Provide either \"to\" date or \"add_days\".'\n\n const toDt = (toStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(toStr)).setZone(\n zone\n )\n if (!toDt.isValid) return `Error: Invalid to date \"${toStr}\".`\n\n const count = countBusinessDays(fromDt, toDt)\n return `Business days from ${fromStr} to ${toStr}: ${count}`\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"datetime_extended.cjs","names":[],"sources":["../../../src/batteries/tools/datetime_extended/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for parsing natural-language dates and business-calendar calculations.\n *\n * @module @nhtio/adk/batteries/tools/datetime_extended\n *\n * @remarks\n * Pre-constructed bundled tools for the `datetime_extended` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport * as chrono from 'chrono-node'\nimport { Tool } from '@nhtio/adk/common'\nimport { DateTime, IANAZone } from 'luxon'\nimport { validator } from '@nhtio/validation'\n\nfunction resolveZone(timezone: string | undefined): { zone: string; error?: string } {\n if (!timezone) return { zone: 'UTC' }\n if (!IANAZone.isValidZone(timezone)) return { zone: '', error: `Invalid timezone \"${timezone}\".` }\n return { zone: timezone }\n}\n\nfunction countBusinessDays(from: DateTime, to: DateTime): number {\n const forward = to >= from\n const start = forward ? from.startOf('day') : to.startOf('day')\n const end = forward ? to.startOf('day') : from.startOf('day')\n\n const totalDays = Math.round(end.diff(start, 'days').days)\n const fullWeeks = Math.floor(totalDays / 7)\n let bdays = fullWeeks * 5\n\n let cursor = start.plus({ days: fullWeeks * 7 })\n while (cursor < end) {\n cursor = cursor.plus({ days: 1 })\n if (cursor.weekday <= 5) bdays++\n }\n\n return forward ? bdays : -bdays\n}\n\n/**\n * Find the Nth occurrence of a weekday in a given month.\n *\n * @remarks\n * Examples: \"2nd Friday of March 2026\", \"last Monday of January 2025\". Accepts 1st–5th and\n * `last`. Returns an error if the month does not contain that many occurrences of the weekday.\n */\nexport const dateNthWeekdayTool = new Tool({\n name: 'date_nth_weekday',\n description:\n 'Find the Nth occurrence of a weekday in a given month (e.g., \"2nd Friday of March 2026\", \"last Monday of next month\"). Supports 1st–5th and \"last\".',\n inputSchema: validator.object({\n nth: validator\n .string()\n .required()\n .description('Which occurrence: \"1st\", \"2nd\", \"3rd\", \"4th\", \"5th\", or \"last\".'),\n weekday: validator\n .string()\n .valid('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday')\n .required()\n .description('Day of the week.'),\n month: validator.number().required().description('Month number (1–12).'),\n year: validator.number().optional().description('Year (defaults to current year).'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC).'),\n }),\n handler: async (args) => {\n const {\n nth,\n weekday,\n month: rawMonth,\n year: rawYear,\n timezone,\n } = args as {\n nth: string\n weekday: string\n month: number\n year?: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const weekdayNames: Record<string, number> = {\n monday: 1,\n tuesday: 2,\n wednesday: 3,\n thursday: 4,\n friday: 5,\n saturday: 6,\n sunday: 7,\n }\n\n const targetWeekday = weekdayNames[weekday.toLowerCase()]\n const month = Math.floor(rawMonth)\n if (month < 1 || month > 12) return `Error: Month must be 1–12, got ${rawMonth}.`\n\n const year = Math.floor(rawYear ?? DateTime.now().setZone(zone).year)\n const nthRaw = nth.toLowerCase().replace(/\\s/g, '')\n\n const firstOfMonth = DateTime.fromObject({ year, month, day: 1 }, { zone })\n if (!firstOfMonth.isValid) return `Error: Invalid date for ${year}-${month}.`\n\n const occurrences: DateTime[] = []\n let cursor = firstOfMonth\n while (cursor.weekday !== targetWeekday) {\n cursor = cursor.plus({ days: 1 })\n }\n while (cursor.month === month) {\n occurrences.push(cursor)\n cursor = cursor.plus({ weeks: 1 })\n }\n\n let result: DateTime | undefined\n\n if (nthRaw === 'last') {\n result = occurrences[occurrences.length - 1]\n } else {\n const nthMap: Record<string, number> = {\n '1st': 1,\n '1': 1,\n 'first': 1,\n '2nd': 2,\n '2': 2,\n 'second': 2,\n '3rd': 3,\n '3': 3,\n 'third': 3,\n '4th': 4,\n '4': 4,\n 'fourth': 4,\n '5th': 5,\n '5': 5,\n 'fifth': 5,\n }\n const n = nthMap[nthRaw]\n if (!n) return `Error: Invalid nth value \"${nth}\". Use 1st–5th or \"last\".`\n if (n > occurrences.length) {\n return `Error: There is no ${nth} ${weekday} in ${firstOfMonth.toFormat('LLLL yyyy')} (only ${occurrences.length} occurrence${occurrences.length !== 1 ? 's' : ''}).`\n }\n result = occurrences[n - 1]\n }\n\n if (!result) return 'Error: Could not compute the date.'\n\n return `${nth} ${weekday} of ${result.toFormat('LLLL yyyy')}: ${result.toISODate()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy')}`\n },\n})\n\n/**\n * Get calendar metadata for a date.\n *\n * @remarks\n * Reports ISO week number, day of year, calendar quarter, fiscal quarter/year (configurable via\n * `fiscal_year_start_month`), week of month, and whether the date is a weekend. Accepts ISO\n * dates, natural-language (\"next Tuesday\"), and `now`.\n */\nexport const dateCalendarInfoTool = new Tool({\n name: 'date_calendar_info',\n description:\n 'Get calendar metadata for a date: ISO week number, day of year, calendar quarter, fiscal quarter/year, week of month, and whether it is a weekend or weekday.',\n inputSchema: validator.object({\n date: validator\n .string()\n .required()\n .description('ISO 8601 date, natural language date, or \"now\".'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC).'),\n fiscal_year_start_month: validator\n .number()\n .default(1)\n .description('Month when fiscal year starts (1–12, default: 1 = calendar year).'),\n }),\n handler: async (args) => {\n const {\n date: dateStr,\n timezone,\n fiscal_year_start_month: rawFyStart,\n } = args as {\n date: string\n timezone?: string\n fiscal_year_start_month: number\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n let dt: DateTime\n\n if (dateStr.toLowerCase() === 'now') {\n dt = DateTime.now().setZone(zone)\n } else {\n dt = DateTime.fromISO(dateStr, { zone })\n if (!dt.isValid) {\n const parsed = chrono.parseDate(dateStr, new Date())\n if (!parsed) return `Error: Could not parse date \"${dateStr}\".`\n dt = DateTime.fromJSDate(parsed).setZone(zone)\n }\n }\n\n const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n const calendarQuarter = Math.ceil(dt.month / 3)\n\n const monthInFY = (dt.month - fyStart + 12) % 12\n const fiscalQuarter = Math.floor(monthInFY / 3) + 1\n const fiscalYear = dt.month >= fyStart ? dt.year : dt.year - 1\n\n const firstOfMonth = dt.startOf('month')\n const weekOfMonth = Math.ceil((dt.day + firstOfMonth.weekday - 1) / 7)\n\n const dayOfYear = Math.floor(dt.diff(dt.startOf('year'), 'days').days) + 1\n\n const isWeekend = dt.weekday >= 6\n\n const lines = [\n `Date: ${dt.toISODate()} (${dt.toFormat('cccc, LLLL d, yyyy')})`,\n '',\n `ISO week number: ${dt.weekNumber} (ISO year: ${dt.weekYear})`,\n `Day of year: ${dayOfYear} / ${dt.daysInYear}`,\n `Day of week: ${dt.weekday} (${dt.toFormat('cccc')})`,\n `Week of month: ${weekOfMonth}`,\n `Weekend: ${isWeekend ? 'Yes' : 'No'}`,\n '',\n `Calendar quarter: Q${calendarQuarter}`,\n `Fiscal quarter: FQ${fiscalQuarter} (FY${fiscalYear}${fyStart !== 1 ? `, starts month ${fyStart}` : ''})`,\n ]\n\n return lines.join('\\n')\n },\n})\n\n/**\n * Parse a date/time expression from natural language or common formats.\n *\n * @remarks\n * Examples: `\"next Monday\"`, `\"March 5th\"`, `\"in 2 weeks\"`, `\"yesterday\"`. Uses chrono-node for\n * relative parsing. `reference_date` overrides the \"now\" anchor.\n */\nexport const dateParseTool = new Tool({\n name: 'date_parse',\n description:\n 'Parse a date/time string from natural language or common formats (\"next Monday\", \"March 5th\", \"in 2 weeks\", \"yesterday\"). Returns an ISO 8601 date.',\n inputSchema: validator.object({\n text: validator\n .string()\n .required()\n .description('Date/time expression to parse (natural language or structured)'),\n reference_date: validator\n .string()\n .optional()\n .description('ISO date to treat as \"now\" for relative expressions (default: current time)'),\n timezone: validator\n .string()\n .optional()\n .description('IANA timezone for the result (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const {\n text,\n reference_date: referenceDate,\n timezone,\n } = args as {\n text: string\n reference_date?: string\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n let refDate = new Date()\n if (referenceDate) {\n refDate = new Date(referenceDate)\n if (Number.isNaN(refDate.getTime()))\n return `Error: Invalid reference_date \"${referenceDate}\".`\n }\n\n const parsed = chrono.parseDate(text, refDate)\n if (!parsed) return `Error: Could not parse a date from \"${text}\".`\n\n const dt = DateTime.fromJSDate(parsed).setZone(zone)\n return `ISO: ${dt.toISO()}\\nFormatted: ${dt.toFormat('cccc, LLLL d, yyyy h:mm a ZZZZ')}`\n },\n})\n\n/**\n * Get the start or end of a time period containing a given date.\n *\n * @remarks\n * Periods: `day`, `week`, `isoweek` (Monday-start), `month`, `quarter`, `year`. Quarter and year\n * honour `fiscal_year_start_month` for fiscal calendars (default: 1 = calendar year).\n */\nexport const datePeriodTool = new Tool({\n name: 'date_period',\n description:\n 'Get the start or end of a time period (day, week, month, quarter, year) containing a given date. Supports fiscal year offsets.',\n inputSchema: validator.object({\n date: validator.string().required().description('ISO 8601 date or \"now\"'),\n period: validator\n .string()\n .valid('day', 'week', 'isoweek', 'month', 'quarter', 'year')\n .required()\n .description('Time period (isoweek = Monday-start week)'),\n boundary: validator\n .string()\n .valid('start', 'end')\n .required()\n .description('\"start\" for the first moment, \"end\" for the last moment of the period'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC)'),\n fiscal_year_start_month: validator\n .number()\n .default(1)\n .description(\n 'For quarter/year: month number when the fiscal year starts (1–12, default: 1 = calendar year)'\n ),\n }),\n handler: async (args) => {\n const {\n date: dateStr,\n period,\n boundary,\n timezone,\n fiscal_year_start_month: rawFyStart,\n } = args as {\n date: string\n period: 'day' | 'week' | 'isoweek' | 'month' | 'quarter' | 'year'\n boundary: 'start' | 'end'\n timezone?: string\n fiscal_year_start_month: number\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const dt =\n dateStr.toLowerCase() === 'now'\n ? DateTime.now().setZone(zone)\n : DateTime.fromISO(dateStr, { zone })\n if (!dt.isValid) return `Error: Invalid date \"${dateStr}\".`\n\n const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n let result: DateTime\n\n switch (period) {\n case 'day':\n result = boundary === 'start' ? dt.startOf('day') : dt.endOf('day')\n break\n case 'week':\n result = boundary === 'start' ? dt.startOf('week') : dt.endOf('week')\n break\n case 'isoweek':\n result =\n boundary === 'start'\n ? dt.startOf('week').set({ weekday: 1 })\n : dt.startOf('week').set({ weekday: 7 }).endOf('day')\n break\n case 'month':\n result = boundary === 'start' ? dt.startOf('month') : dt.endOf('month')\n break\n case 'quarter': {\n // Months since the fiscal year began (0–11), then the offset into the current quarter.\n // Stepping back that many whole months from the start of `dt`'s month lands on the quarter\n // start — and crucially handles quarters that span the calendar-year boundary (e.g. an\n // FY-Feb Q4 of Nov–Jan): subtracting months rolls the year back correctly, where the old\n // `dt.set({month})` kept the current year and produced a date in the wrong quarter.\n const monthInFY = (dt.month - fyStart + 12) % 12\n const monthsIntoQuarter = monthInFY % 3\n const qStart = dt.startOf('month').minus({ months: monthsIntoQuarter })\n result =\n boundary === 'start' ? qStart : qStart.plus({ months: 3 }).minus({ days: 1 }).endOf('day')\n break\n }\n case 'year':\n if (fyStart === 1) {\n result = boundary === 'start' ? dt.startOf('year') : dt.endOf('year')\n } else {\n const fyStartThis = dt.set({ month: fyStart, day: 1 }).startOf('day')\n const fyBase = dt >= fyStartThis ? fyStartThis : fyStartThis.minus({ years: 1 })\n result =\n boundary === 'start'\n ? fyBase\n : fyBase.plus({ years: 1 }).minus({ days: 1 }).endOf('day')\n }\n break\n }\n\n return `${boundary === 'start' ? 'Start' : 'End'} of ${period} containing ${dateStr}: ${result.toISO()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy h:mm:ss a ZZZZ')}`\n },\n})\n\n/**\n * Count business days between two dates, or compute the date N business days away.\n *\n * @remarks\n * Monday–Friday only; no holiday calendar awareness. Provide either `to` (count between) or\n * `add_days` (compute target date). Negative `add_days` walks backwards.\n */\nexport const dateBusinessDaysTool = new Tool({\n name: 'date_business_days',\n description:\n 'Count business days (Mon–Fri, no holiday awareness) between two dates, or calculate the date that is N business days from a start date.',\n inputSchema: validator.object({\n from: validator.string().required().description('Start date (ISO 8601 or \"now\")'),\n to: validator\n .string()\n .optional()\n .description('End date (ISO 8601 or \"now\") — for counting business days between two dates'),\n add_days: validator\n .number()\n .optional()\n .description('Instead of \"to\": number of business days to add (negative to subtract)'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const {\n from: fromStr,\n to: toStr,\n add_days: addDays,\n timezone,\n } = args as {\n from: string\n to?: string\n add_days?: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const fromDt = (\n fromStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(fromStr)\n ).setZone(zone)\n if (!fromDt.isValid) return `Error: Invalid from date \"${fromStr}\".`\n\n if (addDays !== undefined) {\n const n = Math.floor(addDays)\n let cursor = fromDt.startOf('day')\n let remaining = Math.abs(n)\n const dir = n >= 0 ? 1 : -1\n while (remaining > 0) {\n cursor = cursor.plus({ days: dir })\n if (cursor.weekday <= 5) remaining--\n }\n return `${n >= 0 ? '+' : ''}${n} business day${Math.abs(n) !== 1 ? 's' : ''} from ${fromStr}: ${cursor.toISODate()}\\nFormatted: ${cursor.toFormat('cccc, LLLL d, yyyy')}`\n }\n\n if (!toStr) return 'Error: Provide either \"to\" date or \"add_days\".'\n\n const toDt = (toStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(toStr)).setZone(\n zone\n )\n if (!toDt.isValid) return `Error: Invalid to date \"${toStr}\".`\n\n const count = countBusinessDays(fromDt, toDt)\n return `Business days from ${fromStr} to ${toStr}: ${count}`\n },\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;AAeA,SAAS,YAAY,UAAgE;CACnF,IAAI,CAAC,UAAU,OAAO,EAAE,MAAM,MAAM;CACpC,IAAI,CAAC,MAAA,SAAS,YAAY,QAAQ,GAAG,OAAO;EAAE,MAAM;EAAI,OAAO,qBAAqB,SAAS;CAAI;CACjG,OAAO,EAAE,MAAM,SAAS;AAC1B;AAEA,SAAS,kBAAkB,MAAgB,IAAsB;CAC/D,MAAM,UAAU,MAAM;CACtB,MAAM,QAAQ,UAAU,KAAK,QAAQ,KAAK,IAAI,GAAG,QAAQ,KAAK;CAC9D,MAAM,MAAM,UAAU,GAAG,QAAQ,KAAK,IAAI,KAAK,QAAQ,KAAK;CAE5D,MAAM,YAAY,KAAK,MAAM,IAAI,KAAK,OAAO,MAAM,EAAE,IAAI;CACzD,MAAM,YAAY,KAAK,MAAM,YAAY,CAAC;CAC1C,IAAI,QAAQ,YAAY;CAExB,IAAI,SAAS,MAAM,KAAK,EAAE,MAAM,YAAY,EAAE,CAAC;CAC/C,OAAO,SAAS,KAAK;EACnB,SAAS,OAAO,KAAK,EAAE,MAAM,EAAE,CAAC;EAChC,IAAI,OAAO,WAAW,GAAG;CAC3B;CAEA,OAAO,UAAU,QAAQ,CAAC;AAC5B;;;;;;;;AASA,IAAa,qBAAqB,IAAI,aAAA,KAAK;CACzC,MAAM;CACN,aACE;CACF,aAAa,kBAAA,UAAU,OAAO;EAC5B,KAAK,kBAAA,UACF,OAAO,EACP,SAAS,EACT,YAAY,6EAAiE;EAChF,SAAS,kBAAA,UACN,OAAO,EACP,MAAM,UAAU,WAAW,aAAa,YAAY,UAAU,YAAY,QAAQ,EAClF,SAAS,EACT,YAAY,kBAAkB;EACjC,OAAO,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,sBAAsB;EACvE,MAAM,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,kCAAkC;EAClF,UAAU,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,yCAAyC;CAC/F,CAAC;CACD,SAAS,OAAO,SAAS;EACvB,MAAM,EACJ,KACA,SACA,OAAO,UACP,MAAM,SACN,aACE;EAOJ,MAAM,EAAE,MAAM,OAAO,cAAc,YAAY,QAAQ;EACvD,IAAI,WAAW,OAAO,UAAU;EAYhC,MAAM,gBAAgB;GATpB,QAAQ;GACR,SAAS;GACT,WAAW;GACX,UAAU;GACV,QAAQ;GACR,UAAU;GACV,QAAQ;EAGY,EAAa,QAAQ,YAAY;EACvD,MAAM,QAAQ,KAAK,MAAM,QAAQ;EACjC,IAAI,QAAQ,KAAK,QAAQ,IAAI,OAAO,kCAAkC,SAAS;EAE/E,MAAM,OAAO,KAAK,MAAM,WAAW,MAAA,SAAS,IAAI,EAAE,QAAQ,IAAI,EAAE,IAAI;EACpE,MAAM,SAAS,IAAI,YAAY,EAAE,QAAQ,OAAO,EAAE;EAElD,MAAM,eAAe,MAAA,SAAS,WAAW;GAAE;GAAM;GAAO,KAAK;EAAE,GAAG,EAAE,KAAK,CAAC;EAC1E,IAAI,CAAC,aAAa,SAAS,OAAO,2BAA2B,KAAK,GAAG,MAAM;EAE3E,MAAM,cAA0B,CAAC;EACjC,IAAI,SAAS;EACb,OAAO,OAAO,YAAY,eACxB,SAAS,OAAO,KAAK,EAAE,MAAM,EAAE,CAAC;EAElC,OAAO,OAAO,UAAU,OAAO;GAC7B,YAAY,KAAK,MAAM;GACvB,SAAS,OAAO,KAAK,EAAE,OAAO,EAAE,CAAC;EACnC;EAEA,IAAI;EAEJ,IAAI,WAAW,QACb,SAAS,YAAY,YAAY,SAAS;OACrC;GAkBL,MAAM,IAAI;IAhBR,OAAO;IACP,KAAK;IACL,SAAS;IACT,OAAO;IACP,KAAK;IACL,UAAU;IACV,OAAO;IACP,KAAK;IACL,SAAS;IACT,OAAO;IACP,KAAK;IACL,UAAU;IACV,OAAO;IACP,KAAK;IACL,SAAS;GAED,EAAO;GACjB,IAAI,CAAC,GAAG,OAAO,6BAA6B,IAAI;GAChD,IAAI,IAAI,YAAY,QAClB,OAAO,sBAAsB,IAAI,GAAG,QAAQ,MAAM,aAAa,SAAS,WAAW,EAAE,SAAS,YAAY,OAAO,aAAa,YAAY,WAAW,IAAI,MAAM,GAAG;GAEpK,SAAS,YAAY,IAAI;EAC3B;EAEA,IAAI,CAAC,QAAQ,OAAO;EAEpB,OAAO,GAAG,IAAI,GAAG,QAAQ,MAAM,OAAO,SAAS,WAAW,EAAE,IAAI,OAAO,UAAU,EAAE,eAAe,OAAO,SAAS,oBAAoB;CACxI;AACF,CAAC;;;;;;;;;AAUD,IAAa,uBAAuB,IAAI,aAAA,KAAK;CAC3C,MAAM;CACN,aACE;CACF,aAAa,kBAAA,UAAU,OAAO;EAC5B,MAAM,kBAAA,UACH,OAAO,EACP,SAAS,EACT,YAAY,mDAAiD;EAChE,UAAU,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,yCAAyC;EAC7F,yBAAyB,kBAAA,UACtB,OAAO,EACP,QAAQ,CAAC,EACT,YAAY,mEAAmE;CACpF,CAAC;CACD,SAAS,OAAO,SAAS;EACvB,MAAM,EACJ,MAAM,SACN,UACA,yBAAyB,eACvB;EAKJ,MAAM,EAAE,MAAM,OAAO,cAAc,YAAY,QAAQ;EACvD,IAAI,WAAW,OAAO,UAAU;EAEhC,IAAI;EAEJ,IAAI,QAAQ,YAAY,MAAM,OAC5B,KAAK,MAAA,SAAS,IAAI,EAAE,QAAQ,IAAI;OAC3B;GACL,KAAK,MAAA,SAAS,QAAQ,SAAS,EAAE,KAAK,CAAC;GACvC,IAAI,CAAC,GAAG,SAAS;IACf,MAAM,SAAS,YAAO,UAAU,yBAAS,IAAI,KAAK,CAAC;IACnD,IAAI,CAAC,QAAQ,OAAO,gCAAgC,QAAQ;IAC5D,KAAK,MAAA,SAAS,WAAW,MAAM,EAAE,QAAQ,IAAI;GAC/C;EACF;EAEA,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM,UAAU,CAAC,CAAC;EAEhE,MAAM,kBAAkB,KAAK,KAAK,GAAG,QAAQ,CAAC;EAE9C,MAAM,aAAa,GAAG,QAAQ,UAAU,MAAM;EAC9C,MAAM,gBAAgB,KAAK,MAAM,YAAY,CAAC,IAAI;EAClD,MAAM,aAAa,GAAG,SAAS,UAAU,GAAG,OAAO,GAAG,OAAO;EAE7D,MAAM,eAAe,GAAG,QAAQ,OAAO;EACvC,MAAM,cAAc,KAAK,MAAM,GAAG,MAAM,aAAa,UAAU,KAAK,CAAC;EAErE,MAAM,YAAY,KAAK,MAAM,GAAG,KAAK,GAAG,QAAQ,MAAM,GAAG,MAAM,EAAE,IAAI,IAAI;EAEzE,MAAM,YAAY,GAAG,WAAW;EAehC,OAAO;GAZL,SAAS,GAAG,UAAU,EAAE,IAAI,GAAG,SAAS,oBAAoB,EAAE;GAC9D;GACA,oBAAoB,GAAG,WAAW,cAAc,GAAG,SAAS;GAC5D,gBAAgB,UAAU,KAAK,GAAG;GAClC,gBAAgB,GAAG,QAAQ,IAAI,GAAG,SAAS,MAAM,EAAE;GACnD,kBAAkB;GAClB,YAAY,YAAY,QAAQ;GAChC;GACA,sBAAsB;GACtB,qBAAqB,cAAc,MAAM,aAAa,YAAY,IAAI,kBAAkB,YAAY,GAAG;EAGlG,EAAM,KAAK,IAAI;CACxB;AACF,CAAC;;;;;;;;AASD,IAAa,gBAAgB,IAAI,aAAA,KAAK;CACpC,MAAM;CACN,aACE;CACF,aAAa,kBAAA,UAAU,OAAO;EAC5B,MAAM,kBAAA,UACH,OAAO,EACP,SAAS,EACT,YAAY,gEAAgE;EAC/E,gBAAgB,kBAAA,UACb,OAAO,EACP,SAAS,EACT,YAAY,+EAA6E;EAC5F,UAAU,kBAAA,UACP,OAAO,EACP,SAAS,EACT,YAAY,uDAAuD;CACxE,CAAC;CACD,SAAS,OAAO,SAAS;EACvB,MAAM,EACJ,MACA,gBAAgB,eAChB,aACE;EAKJ,MAAM,EAAE,MAAM,OAAO,cAAc,YAAY,QAAQ;EACvD,IAAI,WAAW,OAAO,UAAU;EAEhC,IAAI,0BAAU,IAAI,KAAK;EACvB,IAAI,eAAe;GACjB,UAAU,IAAI,KAAK,aAAa;GAChC,IAAI,OAAO,MAAM,QAAQ,QAAQ,CAAC,GAChC,OAAO,kCAAkC,cAAc;EAC3D;EAEA,MAAM,SAAS,YAAO,UAAU,MAAM,OAAO;EAC7C,IAAI,CAAC,QAAQ,OAAO,uCAAuC,KAAK;EAEhE,MAAM,KAAK,MAAA,SAAS,WAAW,MAAM,EAAE,QAAQ,IAAI;EACnD,OAAO,QAAQ,GAAG,MAAM,EAAE,eAAe,GAAG,SAAS,gCAAgC;CACvF;AACF,CAAC;;;;;;;;AASD,IAAa,iBAAiB,IAAI,aAAA,KAAK;CACrC,MAAM;CACN,aACE;CACF,aAAa,kBAAA,UAAU,OAAO;EAC5B,MAAM,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,0BAAwB;EACxE,QAAQ,kBAAA,UACL,OAAO,EACP,MAAM,OAAO,QAAQ,WAAW,SAAS,WAAW,MAAM,EAC1D,SAAS,EACT,YAAY,2CAA2C;EAC1D,UAAU,kBAAA,UACP,OAAO,EACP,MAAM,SAAS,KAAK,EACpB,SAAS,EACT,YAAY,2EAAuE;EACtF,UAAU,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,wCAAwC;EAC5F,yBAAyB,kBAAA,UACtB,OAAO,EACP,QAAQ,CAAC,EACT,YACC,+FACF;CACJ,CAAC;CACD,SAAS,OAAO,SAAS;EACvB,MAAM,EACJ,MAAM,SACN,QACA,UACA,UACA,yBAAyB,eACvB;EAOJ,MAAM,EAAE,MAAM,OAAO,cAAc,YAAY,QAAQ;EACvD,IAAI,WAAW,OAAO,UAAU;EAEhC,MAAM,KACJ,QAAQ,YAAY,MAAM,QACtB,MAAA,SAAS,IAAI,EAAE,QAAQ,IAAI,IAC3B,MAAA,SAAS,QAAQ,SAAS,EAAE,KAAK,CAAC;EACxC,IAAI,CAAC,GAAG,SAAS,OAAO,wBAAwB,QAAQ;EAExD,MAAM,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,KAAK,MAAM,UAAU,CAAC,CAAC;EAEhE,IAAI;EAEJ,QAAQ,QAAR;GACE,KAAK;IACH,SAAS,aAAa,UAAU,GAAG,QAAQ,KAAK,IAAI,GAAG,MAAM,KAAK;IAClE;GACF,KAAK;IACH,SAAS,aAAa,UAAU,GAAG,QAAQ,MAAM,IAAI,GAAG,MAAM,MAAM;IACpE;GACF,KAAK;IACH,SACE,aAAa,UACT,GAAG,QAAQ,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,IACrC,GAAG,QAAQ,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE,MAAM,KAAK;IACxD;GACF,KAAK;IACH,SAAS,aAAa,UAAU,GAAG,QAAQ,OAAO,IAAI,GAAG,MAAM,OAAO;IACtE;GACF,KAAK,WAAW;IAOd,MAAM,qBADa,GAAG,QAAQ,UAAU,MAAM,KACR;IACtC,MAAM,SAAS,GAAG,QAAQ,OAAO,EAAE,MAAM,EAAE,QAAQ,kBAAkB,CAAC;IACtE,SACE,aAAa,UAAU,SAAS,OAAO,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK;IAC3F;GACF;GACA,KAAK;IACH,IAAI,YAAY,GACd,SAAS,aAAa,UAAU,GAAG,QAAQ,MAAM,IAAI,GAAG,MAAM,MAAM;SAC/D;KACL,MAAM,cAAc,GAAG,IAAI;MAAE,OAAO;MAAS,KAAK;KAAE,CAAC,EAAE,QAAQ,KAAK;KACpE,MAAM,SAAS,MAAM,cAAc,cAAc,YAAY,MAAM,EAAE,OAAO,EAAE,CAAC;KAC/E,SACE,aAAa,UACT,SACA,OAAO,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK;IAChE;IACA;EACJ;EAEA,OAAO,GAAG,aAAa,UAAU,UAAU,MAAM,MAAM,OAAO,cAAc,QAAQ,IAAI,OAAO,MAAM,EAAE,eAAe,OAAO,SAAS,mCAAmC;CAC3K;AACF,CAAC;;;;;;;;AASD,IAAa,uBAAuB,IAAI,aAAA,KAAK;CAC3C,MAAM;CACN,aACE;CACF,aAAa,kBAAA,UAAU,OAAO;EAC5B,MAAM,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,kCAAgC;EAChF,IAAI,kBAAA,UACD,OAAO,EACP,SAAS,EACT,YAAY,+EAA6E;EAC5F,UAAU,kBAAA,UACP,OAAO,EACP,SAAS,EACT,YAAY,0EAAwE;EACvF,UAAU,kBAAA,UAAU,OAAO,EAAE,SAAS,EAAE,YAAY,wCAAwC;CAC9F,CAAC;CACD,SAAS,OAAO,SAAS;EACvB,MAAM,EACJ,MAAM,SACN,IAAI,OACJ,UAAU,SACV,aACE;EAMJ,MAAM,EAAE,MAAM,OAAO,cAAc,YAAY,QAAQ;EACvD,IAAI,WAAW,OAAO,UAAU;EAEhC,MAAM,UACJ,QAAQ,YAAY,MAAM,QAAQ,MAAA,SAAS,IAAI,IAAI,MAAA,SAAS,QAAQ,OAAO,GAC3E,QAAQ,IAAI;EACd,IAAI,CAAC,OAAO,SAAS,OAAO,6BAA6B,QAAQ;EAEjE,IAAI,YAAY,KAAA,GAAW;GACzB,MAAM,IAAI,KAAK,MAAM,OAAO;GAC5B,IAAI,SAAS,OAAO,QAAQ,KAAK;GACjC,IAAI,YAAY,KAAK,IAAI,CAAC;GAC1B,MAAM,MAAM,KAAK,IAAI,IAAI;GACzB,OAAO,YAAY,GAAG;IACpB,SAAS,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;IAClC,IAAI,OAAO,WAAW,GAAG;GAC3B;GACA,OAAO,GAAG,KAAK,IAAI,MAAM,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC,MAAM,IAAI,MAAM,GAAG,QAAQ,QAAQ,IAAI,OAAO,UAAU,EAAE,eAAe,OAAO,SAAS,oBAAoB;EACxK;EAEA,IAAI,CAAC,OAAO,OAAO;EAEnB,MAAM,QAAQ,MAAM,YAAY,MAAM,QAAQ,MAAA,SAAS,IAAI,IAAI,MAAA,SAAS,QAAQ,KAAK,GAAG,QACtF,IACF;EACA,IAAI,CAAC,KAAK,SAAS,OAAO,2BAA2B,MAAM;EAG3D,OAAO,sBAAsB,QAAQ,MAAM,MAAM,IADnC,kBAAkB,QAAQ,IACa;CACvD;AACF,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as Tool } from "../../tool-
|
|
2
|
-
import "../../common-
|
|
1
|
+
import { t as Tool } from "../../tool-wMYMVl60.mjs";
|
|
2
|
+
import "../../common-DYDUi99O.mjs";
|
|
3
3
|
import { validator } from "@nhtio/validation";
|
|
4
4
|
import { DateTime, IANAZone } from "luxon";
|
|
5
5
|
import * as chrono from "chrono-node";
|
|
@@ -232,14 +232,9 @@ var datePeriodTool = new Tool({
|
|
|
232
232
|
result = boundary === "start" ? dt.startOf("month") : dt.endOf("month");
|
|
233
233
|
break;
|
|
234
234
|
case "quarter": {
|
|
235
|
-
const
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
month: qStartMonth,
|
|
239
|
-
day: 1
|
|
240
|
-
}).startOf("day");
|
|
241
|
-
const adjusted = qStart > dt ? qStart.minus({ months: 3 }) : qStart;
|
|
242
|
-
result = boundary === "start" ? adjusted : adjusted.plus({ months: 3 }).minus({ days: 1 }).endOf("day");
|
|
235
|
+
const monthsIntoQuarter = (dt.month - fyStart + 12) % 12 % 3;
|
|
236
|
+
const qStart = dt.startOf("month").minus({ months: monthsIntoQuarter });
|
|
237
|
+
result = boundary === "start" ? qStart : qStart.plus({ months: 3 }).minus({ days: 1 }).endOf("day");
|
|
243
238
|
break;
|
|
244
239
|
}
|
|
245
240
|
case "year":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datetime_extended.mjs","names":[],"sources":["../../../src/batteries/tools/datetime_extended/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for parsing natural-language dates and business-calendar calculations.\n *\n * @module @nhtio/adk/batteries/tools/datetime_extended\n *\n * @remarks\n * Pre-constructed bundled tools for the `datetime_extended` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport * as chrono from 'chrono-node'\nimport { Tool } from '@nhtio/adk/common'\nimport { DateTime, IANAZone } from 'luxon'\nimport { validator } from '@nhtio/validation'\n\nfunction resolveZone(timezone: string | undefined): { zone: string; error?: string } {\n if (!timezone) return { zone: 'UTC' }\n if (!IANAZone.isValidZone(timezone)) return { zone: '', error: `Invalid timezone \"${timezone}\".` }\n return { zone: timezone }\n}\n\nfunction countBusinessDays(from: DateTime, to: DateTime): number {\n const forward = to >= from\n const start = forward ? from.startOf('day') : to.startOf('day')\n const end = forward ? to.startOf('day') : from.startOf('day')\n\n const totalDays = Math.round(end.diff(start, 'days').days)\n const fullWeeks = Math.floor(totalDays / 7)\n let bdays = fullWeeks * 5\n\n let cursor = start.plus({ days: fullWeeks * 7 })\n while (cursor < end) {\n cursor = cursor.plus({ days: 1 })\n if (cursor.weekday <= 5) bdays++\n }\n\n return forward ? bdays : -bdays\n}\n\n/**\n * Find the Nth occurrence of a weekday in a given month.\n *\n * @remarks\n * Examples: \"2nd Friday of March 2026\", \"last Monday of January 2025\". Accepts 1st–5th and\n * `last`. Returns an error if the month does not contain that many occurrences of the weekday.\n */\nexport const dateNthWeekdayTool = new Tool({\n name: 'date_nth_weekday',\n description:\n 'Find the Nth occurrence of a weekday in a given month (e.g., \"2nd Friday of March 2026\", \"last Monday of next month\"). Supports 1st–5th and \"last\".',\n inputSchema: validator.object({\n nth: validator\n .string()\n .required()\n .description('Which occurrence: \"1st\", \"2nd\", \"3rd\", \"4th\", \"5th\", or \"last\".'),\n weekday: validator\n .string()\n .valid('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday')\n .required()\n .description('Day of the week.'),\n month: validator.number().required().description('Month number (1–12).'),\n year: validator.number().optional().description('Year (defaults to current year).'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC).'),\n }),\n handler: async (args) => {\n const {\n nth,\n weekday,\n month: rawMonth,\n year: rawYear,\n timezone,\n } = args as {\n nth: string\n weekday: string\n month: number\n year?: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const weekdayNames: Record<string, number> = {\n monday: 1,\n tuesday: 2,\n wednesday: 3,\n thursday: 4,\n friday: 5,\n saturday: 6,\n sunday: 7,\n }\n\n const targetWeekday = weekdayNames[weekday.toLowerCase()]\n const month = Math.floor(rawMonth)\n if (month < 1 || month > 12) return `Error: Month must be 1–12, got ${rawMonth}.`\n\n const year = Math.floor(rawYear ?? DateTime.now().setZone(zone).year)\n const nthRaw = nth.toLowerCase().replace(/\\s/g, '')\n\n const firstOfMonth = DateTime.fromObject({ year, month, day: 1 }, { zone })\n if (!firstOfMonth.isValid) return `Error: Invalid date for ${year}-${month}.`\n\n const occurrences: DateTime[] = []\n let cursor = firstOfMonth\n while (cursor.weekday !== targetWeekday) {\n cursor = cursor.plus({ days: 1 })\n }\n while (cursor.month === month) {\n occurrences.push(cursor)\n cursor = cursor.plus({ weeks: 1 })\n }\n\n let result: DateTime | undefined\n\n if (nthRaw === 'last') {\n result = occurrences[occurrences.length - 1]\n } else {\n const nthMap: Record<string, number> = {\n '1st': 1,\n '1': 1,\n 'first': 1,\n '2nd': 2,\n '2': 2,\n 'second': 2,\n '3rd': 3,\n '3': 3,\n 'third': 3,\n '4th': 4,\n '4': 4,\n 'fourth': 4,\n '5th': 5,\n '5': 5,\n 'fifth': 5,\n }\n const n = nthMap[nthRaw]\n if (!n) return `Error: Invalid nth value \"${nth}\". Use 1st–5th or \"last\".`\n if (n > occurrences.length) {\n return `Error: There is no ${nth} ${weekday} in ${firstOfMonth.toFormat('LLLL yyyy')} (only ${occurrences.length} occurrence${occurrences.length !== 1 ? 's' : ''}).`\n }\n result = occurrences[n - 1]\n }\n\n if (!result) return 'Error: Could not compute the date.'\n\n return `${nth} ${weekday} of ${result.toFormat('LLLL yyyy')}: ${result.toISODate()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy')}`\n },\n})\n\n/**\n * Get calendar metadata for a date.\n *\n * @remarks\n * Reports ISO week number, day of year, calendar quarter, fiscal quarter/year (configurable via\n * `fiscal_year_start_month`), week of month, and whether the date is a weekend. Accepts ISO\n * dates, natural-language (\"next Tuesday\"), and `now`.\n */\nexport const dateCalendarInfoTool = new Tool({\n name: 'date_calendar_info',\n description:\n 'Get calendar metadata for a date: ISO week number, day of year, calendar quarter, fiscal quarter/year, week of month, and whether it is a weekend or weekday.',\n inputSchema: validator.object({\n date: validator\n .string()\n .required()\n .description('ISO 8601 date, natural language date, or \"now\".'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC).'),\n fiscal_year_start_month: validator\n .number()\n .default(1)\n .description('Month when fiscal year starts (1–12, default: 1 = calendar year).'),\n }),\n handler: async (args) => {\n const {\n date: dateStr,\n timezone,\n fiscal_year_start_month: rawFyStart,\n } = args as {\n date: string\n timezone?: string\n fiscal_year_start_month: number\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n let dt: DateTime\n\n if (dateStr.toLowerCase() === 'now') {\n dt = DateTime.now().setZone(zone)\n } else {\n dt = DateTime.fromISO(dateStr, { zone })\n if (!dt.isValid) {\n const parsed = chrono.parseDate(dateStr, new Date())\n if (!parsed) return `Error: Could not parse date \"${dateStr}\".`\n dt = DateTime.fromJSDate(parsed).setZone(zone)\n }\n }\n\n const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n const calendarQuarter = Math.ceil(dt.month / 3)\n\n const monthInFY = (dt.month - fyStart + 12) % 12\n const fiscalQuarter = Math.floor(monthInFY / 3) + 1\n const fiscalYear = dt.month >= fyStart ? dt.year : dt.year - 1\n\n const firstOfMonth = dt.startOf('month')\n const weekOfMonth = Math.ceil((dt.day + firstOfMonth.weekday - 1) / 7)\n\n const dayOfYear = Math.floor(dt.diff(dt.startOf('year'), 'days').days) + 1\n\n const isWeekend = dt.weekday >= 6\n\n const lines = [\n `Date: ${dt.toISODate()} (${dt.toFormat('cccc, LLLL d, yyyy')})`,\n '',\n `ISO week number: ${dt.weekNumber} (ISO year: ${dt.weekYear})`,\n `Day of year: ${dayOfYear} / ${dt.daysInYear}`,\n `Day of week: ${dt.weekday} (${dt.toFormat('cccc')})`,\n `Week of month: ${weekOfMonth}`,\n `Weekend: ${isWeekend ? 'Yes' : 'No'}`,\n '',\n `Calendar quarter: Q${calendarQuarter}`,\n `Fiscal quarter: FQ${fiscalQuarter} (FY${fiscalYear}${fyStart !== 1 ? `, starts month ${fyStart}` : ''})`,\n ]\n\n return lines.join('\\n')\n },\n})\n\n/**\n * Parse a date/time expression from natural language or common formats.\n *\n * @remarks\n * Examples: `\"next Monday\"`, `\"March 5th\"`, `\"in 2 weeks\"`, `\"yesterday\"`. Uses chrono-node for\n * relative parsing. `reference_date` overrides the \"now\" anchor.\n */\nexport const dateParseTool = new Tool({\n name: 'date_parse',\n description:\n 'Parse a date/time string from natural language or common formats (\"next Monday\", \"March 5th\", \"in 2 weeks\", \"yesterday\"). Returns an ISO 8601 date.',\n inputSchema: validator.object({\n text: validator\n .string()\n .required()\n .description('Date/time expression to parse (natural language or structured)'),\n reference_date: validator\n .string()\n .optional()\n .description('ISO date to treat as \"now\" for relative expressions (default: current time)'),\n timezone: validator\n .string()\n .optional()\n .description('IANA timezone for the result (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const {\n text,\n reference_date: referenceDate,\n timezone,\n } = args as {\n text: string\n reference_date?: string\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n let refDate = new Date()\n if (referenceDate) {\n refDate = new Date(referenceDate)\n if (Number.isNaN(refDate.getTime()))\n return `Error: Invalid reference_date \"${referenceDate}\".`\n }\n\n const parsed = chrono.parseDate(text, refDate)\n if (!parsed) return `Error: Could not parse a date from \"${text}\".`\n\n const dt = DateTime.fromJSDate(parsed).setZone(zone)\n return `ISO: ${dt.toISO()}\\nFormatted: ${dt.toFormat('cccc, LLLL d, yyyy h:mm a ZZZZ')}`\n },\n})\n\n/**\n * Get the start or end of a time period containing a given date.\n *\n * @remarks\n * Periods: `day`, `week`, `isoweek` (Monday-start), `month`, `quarter`, `year`. Quarter and year\n * honour `fiscal_year_start_month` for fiscal calendars (default: 1 = calendar year).\n */\nexport const datePeriodTool = new Tool({\n name: 'date_period',\n description:\n 'Get the start or end of a time period (day, week, month, quarter, year) containing a given date. Supports fiscal year offsets.',\n inputSchema: validator.object({\n date: validator.string().required().description('ISO 8601 date or \"now\"'),\n period: validator\n .string()\n .valid('day', 'week', 'isoweek', 'month', 'quarter', 'year')\n .required()\n .description('Time period (isoweek = Monday-start week)'),\n boundary: validator\n .string()\n .valid('start', 'end')\n .required()\n .description('\"start\" for the first moment, \"end\" for the last moment of the period'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC)'),\n fiscal_year_start_month: validator\n .number()\n .default(1)\n .description(\n 'For quarter/year: month number when the fiscal year starts (1–12, default: 1 = calendar year)'\n ),\n }),\n handler: async (args) => {\n const {\n date: dateStr,\n period,\n boundary,\n timezone,\n fiscal_year_start_month: rawFyStart,\n } = args as {\n date: string\n period: 'day' | 'week' | 'isoweek' | 'month' | 'quarter' | 'year'\n boundary: 'start' | 'end'\n timezone?: string\n fiscal_year_start_month: number\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const dt =\n dateStr.toLowerCase() === 'now'\n ? DateTime.now().setZone(zone)\n : DateTime.fromISO(dateStr, { zone })\n if (!dt.isValid) return `Error: Invalid date \"${dateStr}\".`\n\n const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n let result: DateTime\n\n switch (period) {\n case 'day':\n result = boundary === 'start' ? dt.startOf('day') : dt.endOf('day')\n break\n case 'week':\n result = boundary === 'start' ? dt.startOf('week') : dt.endOf('week')\n break\n case 'isoweek':\n result =\n boundary === 'start'\n ? dt.startOf('week').set({ weekday: 1 })\n : dt.startOf('week').set({ weekday: 7 }).endOf('day')\n break\n case 'month':\n result = boundary === 'start' ? dt.startOf('month') : dt.endOf('month')\n break\n case 'quarter': {\n const monthInFY = (dt.month - fyStart + 12) % 12\n const qIndex = Math.floor(monthInFY / 3)\n const qStartMonth = ((qIndex * 3 + fyStart - 1) % 12) + 1\n const qStart = dt.set({ month: qStartMonth, day: 1 }).startOf('day')\n const adjusted = qStart > dt ? qStart.minus({ months: 3 }) : qStart\n result =\n boundary === 'start'\n ? adjusted\n : adjusted.plus({ months: 3 }).minus({ days: 1 }).endOf('day')\n break\n }\n case 'year':\n if (fyStart === 1) {\n result = boundary === 'start' ? dt.startOf('year') : dt.endOf('year')\n } else {\n const fyStartThis = dt.set({ month: fyStart, day: 1 }).startOf('day')\n const fyBase = dt >= fyStartThis ? fyStartThis : fyStartThis.minus({ years: 1 })\n result =\n boundary === 'start'\n ? fyBase\n : fyBase.plus({ years: 1 }).minus({ days: 1 }).endOf('day')\n }\n break\n }\n\n return `${boundary === 'start' ? 'Start' : 'End'} of ${period} containing ${dateStr}: ${result.toISO()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy h:mm:ss a ZZZZ')}`\n },\n})\n\n/**\n * Count business days between two dates, or compute the date N business days away.\n *\n * @remarks\n * Monday–Friday only; no holiday calendar awareness. Provide either `to` (count between) or\n * `add_days` (compute target date). Negative `add_days` walks backwards.\n */\nexport const dateBusinessDaysTool = new Tool({\n name: 'date_business_days',\n description:\n 'Count business days (Mon–Fri, no holiday awareness) between two dates, or calculate the date that is N business days from a start date.',\n inputSchema: validator.object({\n from: validator.string().required().description('Start date (ISO 8601 or \"now\")'),\n to: validator\n .string()\n .optional()\n .description('End date (ISO 8601 or \"now\") — for counting business days between two dates'),\n add_days: validator\n .number()\n .optional()\n .description('Instead of \"to\": number of business days to add (negative to subtract)'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const {\n from: fromStr,\n to: toStr,\n add_days: addDays,\n timezone,\n } = args as {\n from: string\n to?: string\n add_days?: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const fromDt = (\n fromStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(fromStr)\n ).setZone(zone)\n if (!fromDt.isValid) return `Error: Invalid from date \"${fromStr}\".`\n\n if (addDays !== undefined) {\n const n = Math.floor(addDays)\n let cursor = fromDt.startOf('day')\n let remaining = Math.abs(n)\n const dir = n >= 0 ? 1 : -1\n while (remaining > 0) {\n cursor = cursor.plus({ days: dir })\n if (cursor.weekday <= 5) remaining--\n }\n return `${n >= 0 ? '+' : ''}${n} business day${Math.abs(n) !== 1 ? 's' : ''} from ${fromStr}: ${cursor.toISODate()}\\nFormatted: ${cursor.toFormat('cccc, LLLL d, yyyy')}`\n }\n\n if (!toStr) return 'Error: Provide either \"to\" date or \"add_days\".'\n\n const toDt = (toStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(toStr)).setZone(\n zone\n )\n if (!toDt.isValid) return `Error: Invalid to date \"${toStr}\".`\n\n const count = countBusinessDays(fromDt, toDt)\n return `Business days from ${fromStr} to ${toStr}: ${count}`\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"datetime_extended.mjs","names":[],"sources":["../../../src/batteries/tools/datetime_extended/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for parsing natural-language dates and business-calendar calculations.\n *\n * @module @nhtio/adk/batteries/tools/datetime_extended\n *\n * @remarks\n * Pre-constructed bundled tools for the `datetime_extended` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport * as chrono from 'chrono-node'\nimport { Tool } from '@nhtio/adk/common'\nimport { DateTime, IANAZone } from 'luxon'\nimport { validator } from '@nhtio/validation'\n\nfunction resolveZone(timezone: string | undefined): { zone: string; error?: string } {\n if (!timezone) return { zone: 'UTC' }\n if (!IANAZone.isValidZone(timezone)) return { zone: '', error: `Invalid timezone \"${timezone}\".` }\n return { zone: timezone }\n}\n\nfunction countBusinessDays(from: DateTime, to: DateTime): number {\n const forward = to >= from\n const start = forward ? from.startOf('day') : to.startOf('day')\n const end = forward ? to.startOf('day') : from.startOf('day')\n\n const totalDays = Math.round(end.diff(start, 'days').days)\n const fullWeeks = Math.floor(totalDays / 7)\n let bdays = fullWeeks * 5\n\n let cursor = start.plus({ days: fullWeeks * 7 })\n while (cursor < end) {\n cursor = cursor.plus({ days: 1 })\n if (cursor.weekday <= 5) bdays++\n }\n\n return forward ? bdays : -bdays\n}\n\n/**\n * Find the Nth occurrence of a weekday in a given month.\n *\n * @remarks\n * Examples: \"2nd Friday of March 2026\", \"last Monday of January 2025\". Accepts 1st–5th and\n * `last`. Returns an error if the month does not contain that many occurrences of the weekday.\n */\nexport const dateNthWeekdayTool = new Tool({\n name: 'date_nth_weekday',\n description:\n 'Find the Nth occurrence of a weekday in a given month (e.g., \"2nd Friday of March 2026\", \"last Monday of next month\"). Supports 1st–5th and \"last\".',\n inputSchema: validator.object({\n nth: validator\n .string()\n .required()\n .description('Which occurrence: \"1st\", \"2nd\", \"3rd\", \"4th\", \"5th\", or \"last\".'),\n weekday: validator\n .string()\n .valid('monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday')\n .required()\n .description('Day of the week.'),\n month: validator.number().required().description('Month number (1–12).'),\n year: validator.number().optional().description('Year (defaults to current year).'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC).'),\n }),\n handler: async (args) => {\n const {\n nth,\n weekday,\n month: rawMonth,\n year: rawYear,\n timezone,\n } = args as {\n nth: string\n weekday: string\n month: number\n year?: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const weekdayNames: Record<string, number> = {\n monday: 1,\n tuesday: 2,\n wednesday: 3,\n thursday: 4,\n friday: 5,\n saturday: 6,\n sunday: 7,\n }\n\n const targetWeekday = weekdayNames[weekday.toLowerCase()]\n const month = Math.floor(rawMonth)\n if (month < 1 || month > 12) return `Error: Month must be 1–12, got ${rawMonth}.`\n\n const year = Math.floor(rawYear ?? DateTime.now().setZone(zone).year)\n const nthRaw = nth.toLowerCase().replace(/\\s/g, '')\n\n const firstOfMonth = DateTime.fromObject({ year, month, day: 1 }, { zone })\n if (!firstOfMonth.isValid) return `Error: Invalid date for ${year}-${month}.`\n\n const occurrences: DateTime[] = []\n let cursor = firstOfMonth\n while (cursor.weekday !== targetWeekday) {\n cursor = cursor.plus({ days: 1 })\n }\n while (cursor.month === month) {\n occurrences.push(cursor)\n cursor = cursor.plus({ weeks: 1 })\n }\n\n let result: DateTime | undefined\n\n if (nthRaw === 'last') {\n result = occurrences[occurrences.length - 1]\n } else {\n const nthMap: Record<string, number> = {\n '1st': 1,\n '1': 1,\n 'first': 1,\n '2nd': 2,\n '2': 2,\n 'second': 2,\n '3rd': 3,\n '3': 3,\n 'third': 3,\n '4th': 4,\n '4': 4,\n 'fourth': 4,\n '5th': 5,\n '5': 5,\n 'fifth': 5,\n }\n const n = nthMap[nthRaw]\n if (!n) return `Error: Invalid nth value \"${nth}\". Use 1st–5th or \"last\".`\n if (n > occurrences.length) {\n return `Error: There is no ${nth} ${weekday} in ${firstOfMonth.toFormat('LLLL yyyy')} (only ${occurrences.length} occurrence${occurrences.length !== 1 ? 's' : ''}).`\n }\n result = occurrences[n - 1]\n }\n\n if (!result) return 'Error: Could not compute the date.'\n\n return `${nth} ${weekday} of ${result.toFormat('LLLL yyyy')}: ${result.toISODate()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy')}`\n },\n})\n\n/**\n * Get calendar metadata for a date.\n *\n * @remarks\n * Reports ISO week number, day of year, calendar quarter, fiscal quarter/year (configurable via\n * `fiscal_year_start_month`), week of month, and whether the date is a weekend. Accepts ISO\n * dates, natural-language (\"next Tuesday\"), and `now`.\n */\nexport const dateCalendarInfoTool = new Tool({\n name: 'date_calendar_info',\n description:\n 'Get calendar metadata for a date: ISO week number, day of year, calendar quarter, fiscal quarter/year, week of month, and whether it is a weekend or weekday.',\n inputSchema: validator.object({\n date: validator\n .string()\n .required()\n .description('ISO 8601 date, natural language date, or \"now\".'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC).'),\n fiscal_year_start_month: validator\n .number()\n .default(1)\n .description('Month when fiscal year starts (1–12, default: 1 = calendar year).'),\n }),\n handler: async (args) => {\n const {\n date: dateStr,\n timezone,\n fiscal_year_start_month: rawFyStart,\n } = args as {\n date: string\n timezone?: string\n fiscal_year_start_month: number\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n let dt: DateTime\n\n if (dateStr.toLowerCase() === 'now') {\n dt = DateTime.now().setZone(zone)\n } else {\n dt = DateTime.fromISO(dateStr, { zone })\n if (!dt.isValid) {\n const parsed = chrono.parseDate(dateStr, new Date())\n if (!parsed) return `Error: Could not parse date \"${dateStr}\".`\n dt = DateTime.fromJSDate(parsed).setZone(zone)\n }\n }\n\n const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n const calendarQuarter = Math.ceil(dt.month / 3)\n\n const monthInFY = (dt.month - fyStart + 12) % 12\n const fiscalQuarter = Math.floor(monthInFY / 3) + 1\n const fiscalYear = dt.month >= fyStart ? dt.year : dt.year - 1\n\n const firstOfMonth = dt.startOf('month')\n const weekOfMonth = Math.ceil((dt.day + firstOfMonth.weekday - 1) / 7)\n\n const dayOfYear = Math.floor(dt.diff(dt.startOf('year'), 'days').days) + 1\n\n const isWeekend = dt.weekday >= 6\n\n const lines = [\n `Date: ${dt.toISODate()} (${dt.toFormat('cccc, LLLL d, yyyy')})`,\n '',\n `ISO week number: ${dt.weekNumber} (ISO year: ${dt.weekYear})`,\n `Day of year: ${dayOfYear} / ${dt.daysInYear}`,\n `Day of week: ${dt.weekday} (${dt.toFormat('cccc')})`,\n `Week of month: ${weekOfMonth}`,\n `Weekend: ${isWeekend ? 'Yes' : 'No'}`,\n '',\n `Calendar quarter: Q${calendarQuarter}`,\n `Fiscal quarter: FQ${fiscalQuarter} (FY${fiscalYear}${fyStart !== 1 ? `, starts month ${fyStart}` : ''})`,\n ]\n\n return lines.join('\\n')\n },\n})\n\n/**\n * Parse a date/time expression from natural language or common formats.\n *\n * @remarks\n * Examples: `\"next Monday\"`, `\"March 5th\"`, `\"in 2 weeks\"`, `\"yesterday\"`. Uses chrono-node for\n * relative parsing. `reference_date` overrides the \"now\" anchor.\n */\nexport const dateParseTool = new Tool({\n name: 'date_parse',\n description:\n 'Parse a date/time string from natural language or common formats (\"next Monday\", \"March 5th\", \"in 2 weeks\", \"yesterday\"). Returns an ISO 8601 date.',\n inputSchema: validator.object({\n text: validator\n .string()\n .required()\n .description('Date/time expression to parse (natural language or structured)'),\n reference_date: validator\n .string()\n .optional()\n .description('ISO date to treat as \"now\" for relative expressions (default: current time)'),\n timezone: validator\n .string()\n .optional()\n .description('IANA timezone for the result (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const {\n text,\n reference_date: referenceDate,\n timezone,\n } = args as {\n text: string\n reference_date?: string\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n let refDate = new Date()\n if (referenceDate) {\n refDate = new Date(referenceDate)\n if (Number.isNaN(refDate.getTime()))\n return `Error: Invalid reference_date \"${referenceDate}\".`\n }\n\n const parsed = chrono.parseDate(text, refDate)\n if (!parsed) return `Error: Could not parse a date from \"${text}\".`\n\n const dt = DateTime.fromJSDate(parsed).setZone(zone)\n return `ISO: ${dt.toISO()}\\nFormatted: ${dt.toFormat('cccc, LLLL d, yyyy h:mm a ZZZZ')}`\n },\n})\n\n/**\n * Get the start or end of a time period containing a given date.\n *\n * @remarks\n * Periods: `day`, `week`, `isoweek` (Monday-start), `month`, `quarter`, `year`. Quarter and year\n * honour `fiscal_year_start_month` for fiscal calendars (default: 1 = calendar year).\n */\nexport const datePeriodTool = new Tool({\n name: 'date_period',\n description:\n 'Get the start or end of a time period (day, week, month, quarter, year) containing a given date. Supports fiscal year offsets.',\n inputSchema: validator.object({\n date: validator.string().required().description('ISO 8601 date or \"now\"'),\n period: validator\n .string()\n .valid('day', 'week', 'isoweek', 'month', 'quarter', 'year')\n .required()\n .description('Time period (isoweek = Monday-start week)'),\n boundary: validator\n .string()\n .valid('start', 'end')\n .required()\n .description('\"start\" for the first moment, \"end\" for the last moment of the period'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC)'),\n fiscal_year_start_month: validator\n .number()\n .default(1)\n .description(\n 'For quarter/year: month number when the fiscal year starts (1–12, default: 1 = calendar year)'\n ),\n }),\n handler: async (args) => {\n const {\n date: dateStr,\n period,\n boundary,\n timezone,\n fiscal_year_start_month: rawFyStart,\n } = args as {\n date: string\n period: 'day' | 'week' | 'isoweek' | 'month' | 'quarter' | 'year'\n boundary: 'start' | 'end'\n timezone?: string\n fiscal_year_start_month: number\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const dt =\n dateStr.toLowerCase() === 'now'\n ? DateTime.now().setZone(zone)\n : DateTime.fromISO(dateStr, { zone })\n if (!dt.isValid) return `Error: Invalid date \"${dateStr}\".`\n\n const fyStart = Math.max(1, Math.min(12, Math.floor(rawFyStart)))\n\n let result: DateTime\n\n switch (period) {\n case 'day':\n result = boundary === 'start' ? dt.startOf('day') : dt.endOf('day')\n break\n case 'week':\n result = boundary === 'start' ? dt.startOf('week') : dt.endOf('week')\n break\n case 'isoweek':\n result =\n boundary === 'start'\n ? dt.startOf('week').set({ weekday: 1 })\n : dt.startOf('week').set({ weekday: 7 }).endOf('day')\n break\n case 'month':\n result = boundary === 'start' ? dt.startOf('month') : dt.endOf('month')\n break\n case 'quarter': {\n // Months since the fiscal year began (0–11), then the offset into the current quarter.\n // Stepping back that many whole months from the start of `dt`'s month lands on the quarter\n // start — and crucially handles quarters that span the calendar-year boundary (e.g. an\n // FY-Feb Q4 of Nov–Jan): subtracting months rolls the year back correctly, where the old\n // `dt.set({month})` kept the current year and produced a date in the wrong quarter.\n const monthInFY = (dt.month - fyStart + 12) % 12\n const monthsIntoQuarter = monthInFY % 3\n const qStart = dt.startOf('month').minus({ months: monthsIntoQuarter })\n result =\n boundary === 'start' ? qStart : qStart.plus({ months: 3 }).minus({ days: 1 }).endOf('day')\n break\n }\n case 'year':\n if (fyStart === 1) {\n result = boundary === 'start' ? dt.startOf('year') : dt.endOf('year')\n } else {\n const fyStartThis = dt.set({ month: fyStart, day: 1 }).startOf('day')\n const fyBase = dt >= fyStartThis ? fyStartThis : fyStartThis.minus({ years: 1 })\n result =\n boundary === 'start'\n ? fyBase\n : fyBase.plus({ years: 1 }).minus({ days: 1 }).endOf('day')\n }\n break\n }\n\n return `${boundary === 'start' ? 'Start' : 'End'} of ${period} containing ${dateStr}: ${result.toISO()}\\nFormatted: ${result.toFormat('cccc, LLLL d, yyyy h:mm:ss a ZZZZ')}`\n },\n})\n\n/**\n * Count business days between two dates, or compute the date N business days away.\n *\n * @remarks\n * Monday–Friday only; no holiday calendar awareness. Provide either `to` (count between) or\n * `add_days` (compute target date). Negative `add_days` walks backwards.\n */\nexport const dateBusinessDaysTool = new Tool({\n name: 'date_business_days',\n description:\n 'Count business days (Mon–Fri, no holiday awareness) between two dates, or calculate the date that is N business days from a start date.',\n inputSchema: validator.object({\n from: validator.string().required().description('Start date (ISO 8601 or \"now\")'),\n to: validator\n .string()\n .optional()\n .description('End date (ISO 8601 or \"now\") — for counting business days between two dates'),\n add_days: validator\n .number()\n .optional()\n .description('Instead of \"to\": number of business days to add (negative to subtract)'),\n timezone: validator.string().optional().description('IANA timezone (optional, defaults UTC)'),\n }),\n handler: async (args) => {\n const {\n from: fromStr,\n to: toStr,\n add_days: addDays,\n timezone,\n } = args as {\n from: string\n to?: string\n add_days?: number\n timezone?: string\n }\n const { zone, error: zoneError } = resolveZone(timezone)\n if (zoneError) return `Error: ${zoneError}`\n\n const fromDt = (\n fromStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(fromStr)\n ).setZone(zone)\n if (!fromDt.isValid) return `Error: Invalid from date \"${fromStr}\".`\n\n if (addDays !== undefined) {\n const n = Math.floor(addDays)\n let cursor = fromDt.startOf('day')\n let remaining = Math.abs(n)\n const dir = n >= 0 ? 1 : -1\n while (remaining > 0) {\n cursor = cursor.plus({ days: dir })\n if (cursor.weekday <= 5) remaining--\n }\n return `${n >= 0 ? '+' : ''}${n} business day${Math.abs(n) !== 1 ? 's' : ''} from ${fromStr}: ${cursor.toISODate()}\\nFormatted: ${cursor.toFormat('cccc, LLLL d, yyyy')}`\n }\n\n if (!toStr) return 'Error: Provide either \"to\" date or \"add_days\".'\n\n const toDt = (toStr.toLowerCase() === 'now' ? DateTime.now() : DateTime.fromISO(toStr)).setZone(\n zone\n )\n if (!toDt.isValid) return `Error: Invalid to date \"${toStr}\".`\n\n const count = countBusinessDays(fromDt, toDt)\n return `Business days from ${fromStr} to ${toStr}: ${count}`\n },\n})\n"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Ble4zEEl.js");
|
|
3
|
-
const require_tool = require("../../tool-
|
|
4
|
-
require("../../common-
|
|
3
|
+
const require_tool = require("../../tool-D5WGVIcI.js");
|
|
4
|
+
require("../../common-DZl3ADJs.js");
|
|
5
5
|
let _nhtio_validation = require("@nhtio/validation");
|
|
6
6
|
let luxon = require("luxon");
|
|
7
7
|
//#region src/batteries/tools/datetime_math/index.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as Tool } from "../../tool-
|
|
2
|
-
import "../../common-
|
|
1
|
+
import { t as Tool } from "../../tool-wMYMVl60.mjs";
|
|
2
|
+
import "../../common-DYDUi99O.mjs";
|
|
3
3
|
import { validator } from "@nhtio/validation";
|
|
4
4
|
import { DateTime, Duration, IANAZone } from "luxon";
|
|
5
5
|
//#region src/batteries/tools/datetime_math/index.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Ble4zEEl.js");
|
|
3
|
-
const require_tool_registry = require("../../tool_registry-
|
|
4
|
-
const require_tool = require("../../tool-
|
|
5
|
-
require("../../common-
|
|
3
|
+
const require_tool_registry = require("../../tool_registry-CKJPze3j.js");
|
|
4
|
+
const require_tool = require("../../tool-D5WGVIcI.js");
|
|
5
|
+
require("../../common-DZl3ADJs.js");
|
|
6
6
|
require("../../guards.cjs");
|
|
7
7
|
let _nhtio_validation = require("@nhtio/validation");
|
|
8
8
|
//#region src/batteries/tools/encoding/index.ts
|
|
@@ -28,6 +28,15 @@ var base64ToUtf8 = (b64) => {
|
|
|
28
28
|
return new TextDecoder().decode(bytes);
|
|
29
29
|
};
|
|
30
30
|
/**
|
|
31
|
+
* Convert a numeric HTML-entity code point to its string, handling astral characters correctly.
|
|
32
|
+
* Returns the original entity text `fallback` for code points outside the valid Unicode range
|
|
33
|
+
* (0 – 0x10FFFF) so `String.fromCodePoint` never throws a RangeError.
|
|
34
|
+
*/
|
|
35
|
+
var codePointToString = (cp, fallback) => {
|
|
36
|
+
if (!Number.isInteger(cp) || cp < 0 || cp > 1114111) return fallback;
|
|
37
|
+
return String.fromCodePoint(cp);
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
31
40
|
* Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.
|
|
32
41
|
*
|
|
33
42
|
* @remarks
|
|
@@ -56,7 +65,7 @@ var encodeTextTool = new require_tool.Tool({
|
|
|
56
65
|
}
|
|
57
66
|
if (scheme === "html_entities") {
|
|
58
67
|
if (direction === "encode") return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
59
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, "\"").replace(/'/g, "'").replace(/&#(\d+);/g, (
|
|
68
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, "\"").replace(/'/g, "'").replace(/&#(\d+);/g, (m, code) => codePointToString(Number.parseInt(code, 10), m)).replace(/&#x([0-9a-fA-F]+);/g, (m, hex) => codePointToString(Number.parseInt(hex, 16), m));
|
|
60
69
|
}
|
|
61
70
|
return `Error: Unknown scheme "${scheme}".`;
|
|
62
71
|
} catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.cjs","names":[],"sources":["../../../src/batteries/tools/encoding/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for common text encodings and decoding operations.\n *\n * @module @nhtio/adk/batteries/tools/encoding\n *\n * @remarks\n * Pre-constructed bundled tools for the `encoding` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\n\nconst utf8ToBase64 = (text: string): string => {\n const bytes = new TextEncoder().encode(text)\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return globalThis.btoa(binary)\n}\n\nconst base64ToUtf8 = (b64: string): string => {\n const binary = globalThis.atob(b64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n return new TextDecoder().decode(bytes)\n}\n\n/**\n * Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.\n *\n * @remarks\n * `base64` uses the portable `globalThis.btoa`/`atob` pair so the tool works in browsers, Node,\n * and edge runtimes. Encoding/decoding errors are returned as `Error:` strings rather than\n * thrown so the model can react in-line.\n */\nexport const encodeTextTool = new Tool({\n name: 'encode_text',\n description:\n 'Encode or decode text using common schemes: base64, url (percent-encoding), html_entities. Specify direction: encode or decode.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to encode or decode'),\n scheme: validator\n .string()\n .valid('base64', 'url', 'html_entities')\n .required()\n .description('Encoding scheme'),\n direction: validator\n .string()\n .valid('encode', 'decode')\n .default('encode')\n .description('Whether to encode or decode (default: encode)'),\n }),\n handler: async (args) => {\n const { text, scheme, direction } = args as {\n text: string\n scheme: string\n direction: string\n }\n\n try {\n if (scheme === 'base64') {\n if (direction === 'encode') return utf8ToBase64(text)\n return base64ToUtf8(text)\n }\n\n if (scheme === 'url') {\n if (direction === 'encode') return encodeURIComponent(text)\n return decodeURIComponent(text)\n }\n\n if (scheme === 'html_entities') {\n if (direction === 'encode') {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n }\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&#(\\d+);/g, (_, code: string) => String.fromCharCode(Number.parseInt(code, 10)))\n .replace(/&#x([0-9a-fA-F]+);/g, (_, hex: string) =>\n String.fromCharCode(Number.parseInt(hex, 16))\n )\n }\n\n return `Error: Unknown scheme \"${scheme}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Escape or unescape special characters for a target context.\n *\n * @remarks\n * Supports `json_string`, `regex`, `csv_field`, `sql_like`, and `markdown` targets. Returns\n * an error string for unknown targets rather than throwing.\n */\nexport const textEscapeTool = new Tool({\n name: 'text_escape',\n description:\n 'Escape or unescape special characters for a target context: json_string, regex, csv_field, sql_like, markdown.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to escape or unescape'),\n target: validator\n .string()\n .valid('json_string', 'regex', 'csv_field', 'sql_like', 'markdown')\n .required()\n .description('Target context for escaping'),\n direction: validator\n .string()\n .valid('escape', 'unescape')\n .default('escape')\n .description('Whether to escape or unescape (default: escape)'),\n }),\n handler: async (args) => {\n const { text, target, direction } = args as {\n text: string\n target: string\n direction: string\n }\n\n try {\n if (target === 'json_string') {\n if (direction === 'escape') return JSON.stringify(text).slice(1, -1)\n return JSON.parse(`\"${text}\"`) as string\n }\n\n if (target === 'regex') {\n if (direction === 'escape') return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([.*+?^${}()|[\\]\\\\])/g, '$1')\n }\n\n if (target === 'csv_field') {\n if (direction === 'escape') {\n if (/[,\"\\n\\r]/.test(text)) return `\"${text.replace(/\"/g, '\"\"')}\"`\n return text\n }\n if (text.startsWith('\"') && text.endsWith('\"')) {\n return text.slice(1, -1).replace(/\"\"/g, '\"')\n }\n return text\n }\n\n if (target === 'sql_like') {\n if (direction === 'escape') return text.replace(/[%_\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([%_\\\\])/g, '$1')\n }\n\n if (target === 'markdown') {\n const mdChars = /[\\\\`*_{}[\\]()#+\\-.!|]/g\n if (direction === 'escape') return text.replace(mdChars, '\\\\$&')\n return text.replace(/\\\\([\\\\`*_{}[\\]()#+\\-.!|])/g, '$1')\n }\n\n return `Error: Unknown target \"${target}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Normalize Unicode text or extract code points.\n *\n * @remarks\n * Operations: NFC, NFD, NFKC, NFKD Unicode normalization forms (via `String.prototype.normalize`),\n * `strip_accents` (NFD-decompose, remove combining diacritics, re-compose to NFC), or\n * `code_points` (one `U+HHHH (char)` per line).\n */\nexport const unicodeNormalizeTool = new Tool({\n name: 'unicode_normalize',\n description:\n 'Normalize Unicode text (NFC, NFD, NFKC, NFKD), strip accents/diacritics, or get Unicode code points for each character.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to process'),\n operation: validator\n .string()\n .valid('nfc', 'nfd', 'nfkc', 'nfkd', 'strip_accents', 'code_points')\n .required()\n .description(\n 'Operation: NFC/NFD/NFKC/NFKD normalization, strip_accents (remove diacritics), or code_points (list hex values)'\n ),\n }),\n handler: async (args) => {\n const { text, operation } = args as { text: string; operation: string }\n\n try {\n if (operation === 'strip_accents') {\n return text.normalize('NFD').replace(/[̀-ͯ]/g, '').normalize('NFC')\n }\n\n if (operation === 'code_points') {\n return [...text]\n .map((ch) => {\n const cp = ch.codePointAt(0)!\n const hex = cp.toString(16).toUpperCase().padStart(4, '0')\n return `U+${hex} (${ch})`\n })\n .join('\\n')\n }\n\n const formMap: Record<string, string> = { nfc: 'NFC', nfd: 'NFD', nfkc: 'NFKC', nfkd: 'NFKD' }\n const form = formMap[operation]\n if (!form) return `Error: Unknown operation \"${operation}\".`\n return text.normalize(form)\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"encoding.cjs","names":[],"sources":["../../../src/batteries/tools/encoding/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for common text encodings and decoding operations.\n *\n * @module @nhtio/adk/batteries/tools/encoding\n *\n * @remarks\n * Pre-constructed bundled tools for the `encoding` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\n\nconst utf8ToBase64 = (text: string): string => {\n const bytes = new TextEncoder().encode(text)\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return globalThis.btoa(binary)\n}\n\nconst base64ToUtf8 = (b64: string): string => {\n const binary = globalThis.atob(b64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n return new TextDecoder().decode(bytes)\n}\n\n/**\n * Convert a numeric HTML-entity code point to its string, handling astral characters correctly.\n * Returns the original entity text `fallback` for code points outside the valid Unicode range\n * (0 – 0x10FFFF) so `String.fromCodePoint` never throws a RangeError.\n */\nconst codePointToString = (cp: number, fallback: string): string => {\n if (!Number.isInteger(cp) || cp < 0 || cp > 0x10ffff) return fallback\n return String.fromCodePoint(cp)\n}\n\n/**\n * Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.\n *\n * @remarks\n * `base64` uses the portable `globalThis.btoa`/`atob` pair so the tool works in browsers, Node,\n * and edge runtimes. Encoding/decoding errors are returned as `Error:` strings rather than\n * thrown so the model can react in-line.\n */\nexport const encodeTextTool = new Tool({\n name: 'encode_text',\n description:\n 'Encode or decode text using common schemes: base64, url (percent-encoding), html_entities. Specify direction: encode or decode.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to encode or decode'),\n scheme: validator\n .string()\n .valid('base64', 'url', 'html_entities')\n .required()\n .description('Encoding scheme'),\n direction: validator\n .string()\n .valid('encode', 'decode')\n .default('encode')\n .description('Whether to encode or decode (default: encode)'),\n }),\n handler: async (args) => {\n const { text, scheme, direction } = args as {\n text: string\n scheme: string\n direction: string\n }\n\n try {\n if (scheme === 'base64') {\n if (direction === 'encode') return utf8ToBase64(text)\n return base64ToUtf8(text)\n }\n\n if (scheme === 'url') {\n if (direction === 'encode') return encodeURIComponent(text)\n return decodeURIComponent(text)\n }\n\n if (scheme === 'html_entities') {\n if (direction === 'encode') {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n }\n return (\n text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n // Use fromCodePoint, not fromCharCode: a numeric entity above U+FFFF (e.g. an emoji like\n // 🎉 = 🎉) is an astral code point. fromCharCode truncates to 16 bits and yields a\n // broken/empty character; fromCodePoint produces the correct surrogate pair. Out-of-range\n // code points (> U+10FFFF) are left as-is rather than throwing.\n .replace(/&#(\\d+);/g, (m, code: string) =>\n codePointToString(Number.parseInt(code, 10), m)\n )\n .replace(/&#x([0-9a-fA-F]+);/g, (m, hex: string) =>\n codePointToString(Number.parseInt(hex, 16), m)\n )\n )\n }\n\n return `Error: Unknown scheme \"${scheme}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Escape or unescape special characters for a target context.\n *\n * @remarks\n * Supports `json_string`, `regex`, `csv_field`, `sql_like`, and `markdown` targets. Returns\n * an error string for unknown targets rather than throwing.\n */\nexport const textEscapeTool = new Tool({\n name: 'text_escape',\n description:\n 'Escape or unescape special characters for a target context: json_string, regex, csv_field, sql_like, markdown.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to escape or unescape'),\n target: validator\n .string()\n .valid('json_string', 'regex', 'csv_field', 'sql_like', 'markdown')\n .required()\n .description('Target context for escaping'),\n direction: validator\n .string()\n .valid('escape', 'unescape')\n .default('escape')\n .description('Whether to escape or unescape (default: escape)'),\n }),\n handler: async (args) => {\n const { text, target, direction } = args as {\n text: string\n target: string\n direction: string\n }\n\n try {\n if (target === 'json_string') {\n if (direction === 'escape') return JSON.stringify(text).slice(1, -1)\n return JSON.parse(`\"${text}\"`) as string\n }\n\n if (target === 'regex') {\n if (direction === 'escape') return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([.*+?^${}()|[\\]\\\\])/g, '$1')\n }\n\n if (target === 'csv_field') {\n if (direction === 'escape') {\n if (/[,\"\\n\\r]/.test(text)) return `\"${text.replace(/\"/g, '\"\"')}\"`\n return text\n }\n if (text.startsWith('\"') && text.endsWith('\"')) {\n return text.slice(1, -1).replace(/\"\"/g, '\"')\n }\n return text\n }\n\n if (target === 'sql_like') {\n if (direction === 'escape') return text.replace(/[%_\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([%_\\\\])/g, '$1')\n }\n\n if (target === 'markdown') {\n const mdChars = /[\\\\`*_{}[\\]()#+\\-.!|]/g\n if (direction === 'escape') return text.replace(mdChars, '\\\\$&')\n return text.replace(/\\\\([\\\\`*_{}[\\]()#+\\-.!|])/g, '$1')\n }\n\n return `Error: Unknown target \"${target}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Normalize Unicode text or extract code points.\n *\n * @remarks\n * Operations: NFC, NFD, NFKC, NFKD Unicode normalization forms (via `String.prototype.normalize`),\n * `strip_accents` (NFD-decompose, remove combining diacritics, re-compose to NFC), or\n * `code_points` (one `U+HHHH (char)` per line).\n */\nexport const unicodeNormalizeTool = new Tool({\n name: 'unicode_normalize',\n description:\n 'Normalize Unicode text (NFC, NFD, NFKC, NFKD), strip accents/diacritics, or get Unicode code points for each character.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to process'),\n operation: validator\n .string()\n .valid('nfc', 'nfd', 'nfkc', 'nfkd', 'strip_accents', 'code_points')\n .required()\n .description(\n 'Operation: NFC/NFD/NFKC/NFKD normalization, strip_accents (remove diacritics), or code_points (list hex values)'\n ),\n }),\n handler: async (args) => {\n const { text, operation } = args as { text: string; operation: string }\n\n try {\n if (operation === 'strip_accents') {\n return text.normalize('NFD').replace(/[̀-ͯ]/g, '').normalize('NFC')\n }\n\n if (operation === 'code_points') {\n return [...text]\n .map((ch) => {\n const cp = ch.codePointAt(0)!\n const hex = cp.toString(16).toUpperCase().padStart(4, '0')\n return `U+${hex} (${ch})`\n })\n .join('\\n')\n }\n\n const formMap: Record<string, string> = { nfc: 'NFC', nfd: 'NFD', nfkc: 'NFKC', nfkd: 'NFKD' }\n const form = formMap[operation]\n if (!form) return `Error: Unknown operation \"${operation}\".`\n return text.normalize(form)\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { o as isError } from "../../tool_registry-
|
|
2
|
-
import { t as Tool } from "../../tool-
|
|
3
|
-
import "../../common-
|
|
1
|
+
import { o as isError } from "../../tool_registry-791Vrjtf.mjs";
|
|
2
|
+
import { t as Tool } from "../../tool-wMYMVl60.mjs";
|
|
3
|
+
import "../../common-DYDUi99O.mjs";
|
|
4
4
|
import "../../guards.mjs";
|
|
5
5
|
import { validator } from "@nhtio/validation";
|
|
6
6
|
//#region src/batteries/tools/encoding/index.ts
|
|
@@ -26,6 +26,15 @@ var base64ToUtf8 = (b64) => {
|
|
|
26
26
|
return new TextDecoder().decode(bytes);
|
|
27
27
|
};
|
|
28
28
|
/**
|
|
29
|
+
* Convert a numeric HTML-entity code point to its string, handling astral characters correctly.
|
|
30
|
+
* Returns the original entity text `fallback` for code points outside the valid Unicode range
|
|
31
|
+
* (0 – 0x10FFFF) so `String.fromCodePoint` never throws a RangeError.
|
|
32
|
+
*/
|
|
33
|
+
var codePointToString = (cp, fallback) => {
|
|
34
|
+
if (!Number.isInteger(cp) || cp < 0 || cp > 1114111) return fallback;
|
|
35
|
+
return String.fromCodePoint(cp);
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
29
38
|
* Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.
|
|
30
39
|
*
|
|
31
40
|
* @remarks
|
|
@@ -54,7 +63,7 @@ var encodeTextTool = new Tool({
|
|
|
54
63
|
}
|
|
55
64
|
if (scheme === "html_entities") {
|
|
56
65
|
if (direction === "encode") return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
57
|
-
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, "\"").replace(/'/g, "'").replace(/&#(\d+);/g, (
|
|
66
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, "\"").replace(/'/g, "'").replace(/&#(\d+);/g, (m, code) => codePointToString(Number.parseInt(code, 10), m)).replace(/&#x([0-9a-fA-F]+);/g, (m, hex) => codePointToString(Number.parseInt(hex, 16), m));
|
|
58
67
|
}
|
|
59
68
|
return `Error: Unknown scheme "${scheme}".`;
|
|
60
69
|
} catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encoding.mjs","names":[],"sources":["../../../src/batteries/tools/encoding/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for common text encodings and decoding operations.\n *\n * @module @nhtio/adk/batteries/tools/encoding\n *\n * @remarks\n * Pre-constructed bundled tools for the `encoding` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\n\nconst utf8ToBase64 = (text: string): string => {\n const bytes = new TextEncoder().encode(text)\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return globalThis.btoa(binary)\n}\n\nconst base64ToUtf8 = (b64: string): string => {\n const binary = globalThis.atob(b64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n return new TextDecoder().decode(bytes)\n}\n\n/**\n * Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.\n *\n * @remarks\n * `base64` uses the portable `globalThis.btoa`/`atob` pair so the tool works in browsers, Node,\n * and edge runtimes. Encoding/decoding errors are returned as `Error:` strings rather than\n * thrown so the model can react in-line.\n */\nexport const encodeTextTool = new Tool({\n name: 'encode_text',\n description:\n 'Encode or decode text using common schemes: base64, url (percent-encoding), html_entities. Specify direction: encode or decode.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to encode or decode'),\n scheme: validator\n .string()\n .valid('base64', 'url', 'html_entities')\n .required()\n .description('Encoding scheme'),\n direction: validator\n .string()\n .valid('encode', 'decode')\n .default('encode')\n .description('Whether to encode or decode (default: encode)'),\n }),\n handler: async (args) => {\n const { text, scheme, direction } = args as {\n text: string\n scheme: string\n direction: string\n }\n\n try {\n if (scheme === 'base64') {\n if (direction === 'encode') return utf8ToBase64(text)\n return base64ToUtf8(text)\n }\n\n if (scheme === 'url') {\n if (direction === 'encode') return encodeURIComponent(text)\n return decodeURIComponent(text)\n }\n\n if (scheme === 'html_entities') {\n if (direction === 'encode') {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n }\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n .replace(/&#(\\d+);/g, (_, code: string) => String.fromCharCode(Number.parseInt(code, 10)))\n .replace(/&#x([0-9a-fA-F]+);/g, (_, hex: string) =>\n String.fromCharCode(Number.parseInt(hex, 16))\n )\n }\n\n return `Error: Unknown scheme \"${scheme}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Escape or unescape special characters for a target context.\n *\n * @remarks\n * Supports `json_string`, `regex`, `csv_field`, `sql_like`, and `markdown` targets. Returns\n * an error string for unknown targets rather than throwing.\n */\nexport const textEscapeTool = new Tool({\n name: 'text_escape',\n description:\n 'Escape or unescape special characters for a target context: json_string, regex, csv_field, sql_like, markdown.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to escape or unescape'),\n target: validator\n .string()\n .valid('json_string', 'regex', 'csv_field', 'sql_like', 'markdown')\n .required()\n .description('Target context for escaping'),\n direction: validator\n .string()\n .valid('escape', 'unescape')\n .default('escape')\n .description('Whether to escape or unescape (default: escape)'),\n }),\n handler: async (args) => {\n const { text, target, direction } = args as {\n text: string\n target: string\n direction: string\n }\n\n try {\n if (target === 'json_string') {\n if (direction === 'escape') return JSON.stringify(text).slice(1, -1)\n return JSON.parse(`\"${text}\"`) as string\n }\n\n if (target === 'regex') {\n if (direction === 'escape') return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([.*+?^${}()|[\\]\\\\])/g, '$1')\n }\n\n if (target === 'csv_field') {\n if (direction === 'escape') {\n if (/[,\"\\n\\r]/.test(text)) return `\"${text.replace(/\"/g, '\"\"')}\"`\n return text\n }\n if (text.startsWith('\"') && text.endsWith('\"')) {\n return text.slice(1, -1).replace(/\"\"/g, '\"')\n }\n return text\n }\n\n if (target === 'sql_like') {\n if (direction === 'escape') return text.replace(/[%_\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([%_\\\\])/g, '$1')\n }\n\n if (target === 'markdown') {\n const mdChars = /[\\\\`*_{}[\\]()#+\\-.!|]/g\n if (direction === 'escape') return text.replace(mdChars, '\\\\$&')\n return text.replace(/\\\\([\\\\`*_{}[\\]()#+\\-.!|])/g, '$1')\n }\n\n return `Error: Unknown target \"${target}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Normalize Unicode text or extract code points.\n *\n * @remarks\n * Operations: NFC, NFD, NFKC, NFKD Unicode normalization forms (via `String.prototype.normalize`),\n * `strip_accents` (NFD-decompose, remove combining diacritics, re-compose to NFC), or\n * `code_points` (one `U+HHHH (char)` per line).\n */\nexport const unicodeNormalizeTool = new Tool({\n name: 'unicode_normalize',\n description:\n 'Normalize Unicode text (NFC, NFD, NFKC, NFKD), strip accents/diacritics, or get Unicode code points for each character.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to process'),\n operation: validator\n .string()\n .valid('nfc', 'nfd', 'nfkc', 'nfkd', 'strip_accents', 'code_points')\n .required()\n .description(\n 'Operation: NFC/NFD/NFKC/NFKD normalization, strip_accents (remove diacritics), or code_points (list hex values)'\n ),\n }),\n handler: async (args) => {\n const { text, operation } = args as { text: string; operation: string }\n\n try {\n if (operation === 'strip_accents') {\n return text.normalize('NFD').replace(/[̀-ͯ]/g, '').normalize('NFC')\n }\n\n if (operation === 'code_points') {\n return [...text]\n .map((ch) => {\n const cp = ch.codePointAt(0)!\n const hex = cp.toString(16).toUpperCase().padStart(4, '0')\n return `U+${hex} (${ch})`\n })\n .join('\\n')\n }\n\n const formMap: Record<string, string> = { nfc: 'NFC', nfd: 'NFD', nfkc: 'NFKC', nfkd: 'NFKD' }\n const form = formMap[operation]\n if (!form) return `Error: Unknown operation \"${operation}\".`\n return text.normalize(form)\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"encoding.mjs","names":[],"sources":["../../../src/batteries/tools/encoding/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for common text encodings and decoding operations.\n *\n * @module @nhtio/adk/batteries/tools/encoding\n *\n * @remarks\n * Pre-constructed bundled tools for the `encoding` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\n\nconst utf8ToBase64 = (text: string): string => {\n const bytes = new TextEncoder().encode(text)\n let binary = ''\n for (const byte of bytes) binary += String.fromCharCode(byte)\n return globalThis.btoa(binary)\n}\n\nconst base64ToUtf8 = (b64: string): string => {\n const binary = globalThis.atob(b64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i)\n return new TextDecoder().decode(bytes)\n}\n\n/**\n * Convert a numeric HTML-entity code point to its string, handling astral characters correctly.\n * Returns the original entity text `fallback` for code points outside the valid Unicode range\n * (0 – 0x10FFFF) so `String.fromCodePoint` never throws a RangeError.\n */\nconst codePointToString = (cp: number, fallback: string): string => {\n if (!Number.isInteger(cp) || cp < 0 || cp > 0x10ffff) return fallback\n return String.fromCodePoint(cp)\n}\n\n/**\n * Encode or decode text using common schemes: base64, url (percent-encoding), html_entities.\n *\n * @remarks\n * `base64` uses the portable `globalThis.btoa`/`atob` pair so the tool works in browsers, Node,\n * and edge runtimes. Encoding/decoding errors are returned as `Error:` strings rather than\n * thrown so the model can react in-line.\n */\nexport const encodeTextTool = new Tool({\n name: 'encode_text',\n description:\n 'Encode or decode text using common schemes: base64, url (percent-encoding), html_entities. Specify direction: encode or decode.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to encode or decode'),\n scheme: validator\n .string()\n .valid('base64', 'url', 'html_entities')\n .required()\n .description('Encoding scheme'),\n direction: validator\n .string()\n .valid('encode', 'decode')\n .default('encode')\n .description('Whether to encode or decode (default: encode)'),\n }),\n handler: async (args) => {\n const { text, scheme, direction } = args as {\n text: string\n scheme: string\n direction: string\n }\n\n try {\n if (scheme === 'base64') {\n if (direction === 'encode') return utf8ToBase64(text)\n return base64ToUtf8(text)\n }\n\n if (scheme === 'url') {\n if (direction === 'encode') return encodeURIComponent(text)\n return decodeURIComponent(text)\n }\n\n if (scheme === 'html_entities') {\n if (direction === 'encode') {\n return text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''')\n }\n return (\n text\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/g, '\"')\n .replace(/'/g, \"'\")\n // Use fromCodePoint, not fromCharCode: a numeric entity above U+FFFF (e.g. an emoji like\n // 🎉 = 🎉) is an astral code point. fromCharCode truncates to 16 bits and yields a\n // broken/empty character; fromCodePoint produces the correct surrogate pair. Out-of-range\n // code points (> U+10FFFF) are left as-is rather than throwing.\n .replace(/&#(\\d+);/g, (m, code: string) =>\n codePointToString(Number.parseInt(code, 10), m)\n )\n .replace(/&#x([0-9a-fA-F]+);/g, (m, hex: string) =>\n codePointToString(Number.parseInt(hex, 16), m)\n )\n )\n }\n\n return `Error: Unknown scheme \"${scheme}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Escape or unescape special characters for a target context.\n *\n * @remarks\n * Supports `json_string`, `regex`, `csv_field`, `sql_like`, and `markdown` targets. Returns\n * an error string for unknown targets rather than throwing.\n */\nexport const textEscapeTool = new Tool({\n name: 'text_escape',\n description:\n 'Escape or unescape special characters for a target context: json_string, regex, csv_field, sql_like, markdown.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to escape or unescape'),\n target: validator\n .string()\n .valid('json_string', 'regex', 'csv_field', 'sql_like', 'markdown')\n .required()\n .description('Target context for escaping'),\n direction: validator\n .string()\n .valid('escape', 'unescape')\n .default('escape')\n .description('Whether to escape or unescape (default: escape)'),\n }),\n handler: async (args) => {\n const { text, target, direction } = args as {\n text: string\n target: string\n direction: string\n }\n\n try {\n if (target === 'json_string') {\n if (direction === 'escape') return JSON.stringify(text).slice(1, -1)\n return JSON.parse(`\"${text}\"`) as string\n }\n\n if (target === 'regex') {\n if (direction === 'escape') return text.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([.*+?^${}()|[\\]\\\\])/g, '$1')\n }\n\n if (target === 'csv_field') {\n if (direction === 'escape') {\n if (/[,\"\\n\\r]/.test(text)) return `\"${text.replace(/\"/g, '\"\"')}\"`\n return text\n }\n if (text.startsWith('\"') && text.endsWith('\"')) {\n return text.slice(1, -1).replace(/\"\"/g, '\"')\n }\n return text\n }\n\n if (target === 'sql_like') {\n if (direction === 'escape') return text.replace(/[%_\\\\]/g, '\\\\$&')\n return text.replace(/\\\\([%_\\\\])/g, '$1')\n }\n\n if (target === 'markdown') {\n const mdChars = /[\\\\`*_{}[\\]()#+\\-.!|]/g\n if (direction === 'escape') return text.replace(mdChars, '\\\\$&')\n return text.replace(/\\\\([\\\\`*_{}[\\]()#+\\-.!|])/g, '$1')\n }\n\n return `Error: Unknown target \"${target}\".`\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Normalize Unicode text or extract code points.\n *\n * @remarks\n * Operations: NFC, NFD, NFKC, NFKD Unicode normalization forms (via `String.prototype.normalize`),\n * `strip_accents` (NFD-decompose, remove combining diacritics, re-compose to NFC), or\n * `code_points` (one `U+HHHH (char)` per line).\n */\nexport const unicodeNormalizeTool = new Tool({\n name: 'unicode_normalize',\n description:\n 'Normalize Unicode text (NFC, NFD, NFKC, NFKD), strip accents/diacritics, or get Unicode code points for each character.',\n inputSchema: validator.object({\n text: validator.string().required().description('Text to process'),\n operation: validator\n .string()\n .valid('nfc', 'nfd', 'nfkc', 'nfkd', 'strip_accents', 'code_points')\n .required()\n .description(\n 'Operation: NFC/NFD/NFKC/NFKD normalization, strip_accents (remove diacritics), or code_points (list hex values)'\n ),\n }),\n handler: async (args) => {\n const { text, operation } = args as { text: string; operation: string }\n\n try {\n if (operation === 'strip_accents') {\n return text.normalize('NFD').replace(/[̀-ͯ]/g, '').normalize('NFC')\n }\n\n if (operation === 'code_points') {\n return [...text]\n .map((ch) => {\n const cp = ch.codePointAt(0)!\n const hex = cp.toString(16).toUpperCase().padStart(4, '0')\n return `U+${hex} (${ch})`\n })\n .join('\\n')\n }\n\n const formMap: Record<string, string> = { nfc: 'NFC', nfd: 'NFD', nfkc: 'NFKC', nfkd: 'NFKD' }\n const form = formMap[operation]\n if (!form) return `Error: Unknown operation \"${operation}\".`\n return text.normalize(form)\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
require("../../chunk-Ble4zEEl.js");
|
|
3
|
-
const require_tool_registry = require("../../tool_registry-
|
|
4
|
-
const require_tool = require("../../tool-
|
|
5
|
-
require("../../common-
|
|
3
|
+
const require_tool_registry = require("../../tool_registry-CKJPze3j.js");
|
|
4
|
+
const require_tool = require("../../tool-D5WGVIcI.js");
|
|
5
|
+
require("../../common-DZl3ADJs.js");
|
|
6
6
|
require("../../guards.cjs");
|
|
7
7
|
let _nhtio_validation = require("@nhtio/validation");
|
|
8
8
|
//#region src/batteries/tools/formatting/index.ts
|
|
@@ -94,7 +94,7 @@ var formatListTool = new require_tool.Tool({
|
|
|
94
94
|
}),
|
|
95
95
|
handler: async (args) => {
|
|
96
96
|
const { items, style, indent: rawIndent } = args;
|
|
97
|
-
const indent = Math.max(0, Math.floor(rawIndent));
|
|
97
|
+
const indent = Math.min(100, Math.max(0, Math.floor(rawIndent)));
|
|
98
98
|
const pad = " ".repeat(indent);
|
|
99
99
|
if (items.length === 0) return "";
|
|
100
100
|
switch (style) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatting.cjs","names":[],"sources":["../../../src/batteries/tools/formatting/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for locale-aware number, list, table, and text formatting.\n *\n * @module @nhtio/adk/batteries/tools/formatting\n *\n * @remarks\n * Pre-constructed bundled tools for the `formatting` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\n\n/**\n * Format a number using locale-aware styles.\n *\n * @remarks\n * Supported styles: `decimal`, `currency`, `percent`, `compact` (e.g. `1.2K`), `scientific`\n * (e.g. `1.2e+3`), and `ordinal` (`1st`, `2nd`, `3rd`). Uses `Intl.NumberFormat` and\n * `Intl.PluralRules` from the JS standard library. Returns an error string for non-finite values\n * or invalid currency-without-currency-code.\n */\nexport const formatNumberTool = new Tool({\n name: 'format_number',\n description:\n 'Format a number using locale-aware styles: decimal, currency, percent, compact (1.2K), scientific (1.2e3), or ordinal (1st/2nd/3rd). Supports locale and precision options.',\n inputSchema: validator.object({\n value: validator.number().required().description('The number to format'),\n style: validator\n .string()\n .valid('decimal', 'currency', 'percent', 'compact', 'scientific', 'ordinal')\n .default('decimal')\n .description('Formatting style (default: decimal)'),\n currency: validator\n .string()\n .optional()\n .description(\n 'ISO 4217 currency code — required when style is \"currency\" (e.g. \"USD\", \"EUR\")'\n ),\n locale: validator.string().default('en-US').description('BCP 47 locale tag (default: \"en-US\")'),\n min_decimals: validator\n .number()\n .optional()\n .description('Minimum fraction digits (default: style-dependent)'),\n max_decimals: validator\n .number()\n .optional()\n .description('Maximum fraction digits (default: style-dependent)'),\n }),\n handler: async (args) => {\n const {\n value,\n style,\n locale,\n currency,\n min_decimals: minDec,\n max_decimals: maxDec,\n } = args as {\n value: number\n style: string\n locale: string\n currency?: string\n min_decimals?: number\n max_decimals?: number\n }\n\n if (!Number.isFinite(value)) return `Error: Value must be a finite number (got ${value}).`\n\n try {\n if (style === 'ordinal') {\n const pr = new Intl.PluralRules(locale, { type: 'ordinal' })\n const suffixes: Record<string, string> = { one: 'st', two: 'nd', few: 'rd', other: 'th' }\n const rule = pr.select(value)\n const suffix = suffixes[rule] ?? 'th'\n return `${new Intl.NumberFormat(locale).format(value)}${suffix}`\n }\n\n if (style === 'scientific') {\n const exp = value === 0 ? 0 : Math.floor(Math.log10(Math.abs(value)))\n const mantissa = value / Math.pow(10, exp)\n const mFormatted = new Intl.NumberFormat(locale, {\n minimumFractionDigits: minDec ?? 2,\n maximumFractionDigits: maxDec ?? 6,\n }).format(mantissa)\n return `${mFormatted}e${exp >= 0 ? '+' : ''}${exp}`\n }\n\n const opts: Intl.NumberFormatOptions = {}\n\n if (style === 'currency') {\n if (!currency) return 'Error: \"currency\" parameter is required when style is \"currency\".'\n opts.style = 'currency'\n opts.currency = currency.toUpperCase()\n } else if (style === 'percent') {\n opts.style = 'percent'\n opts.minimumFractionDigits = minDec ?? 1\n opts.maximumFractionDigits = maxDec ?? 2\n } else if (style === 'compact') {\n opts.notation = 'compact'\n opts.compactDisplay = 'short'\n } else {\n opts.style = 'decimal'\n }\n\n if (minDec !== undefined && style !== 'percent') opts.minimumFractionDigits = minDec\n if (maxDec !== undefined && style !== 'percent') opts.maximumFractionDigits = maxDec\n\n return new Intl.NumberFormat(locale, opts).format(value)\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Format an array of items as a list.\n *\n * @remarks\n * Supported styles: `bullet` (`• item`), `numbered` (`1. item`), `inline_and`\n * (`a, b, and c`), `inline_or` (`a, b, or c`), `newline` (one per line).\n */\nexport const formatListTool = new Tool({\n name: 'format_list',\n description:\n 'Format an array of items as a list. Styles: bullet (• item), numbered (1. item), inline_and (\"a, b, and c\"), inline_or (\"a, b, or c\"), newline (one per line).',\n inputSchema: validator.object({\n items: validator\n .array()\n .items(validator.string())\n .required()\n .description('Array of items to format'),\n style: validator\n .string()\n .valid('bullet', 'numbered', 'inline_and', 'inline_or', 'newline')\n .default('bullet')\n .description('List format style (default: bullet)'),\n indent: validator.number().default(0).description('Spaces to indent each item (default: 0)'),\n }),\n handler: async (args) => {\n const {\n items,\n style,\n indent: rawIndent,\n } = args as {\n items: string[]\n style: string\n indent: number\n }\n const indent = Math.max(0, Math.floor(rawIndent))\n const pad = ' '.repeat(indent)\n\n if (items.length === 0) return ''\n\n switch (style) {\n case 'bullet':\n return items.map((item) => `${pad}• ${item}`).join('\\n')\n case 'numbered':\n return items.map((item, i) => `${pad}${i + 1}. ${item}`).join('\\n')\n case 'newline':\n return items.map((item) => `${pad}${item}`).join('\\n')\n case 'inline_and':\n case 'inline_or': {\n const conj = style === 'inline_and' ? 'and' : 'or'\n if (items.length === 1) return items[0]\n if (items.length === 2) return `${items[0]} ${conj} ${items[1]}`\n const last = items[items.length - 1]\n const rest = items.slice(0, -1)\n return `${rest.join(', ')}, ${conj} ${last}`\n }\n default:\n return `Error: Unknown style \"${style}\".`\n }\n },\n})\n"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"formatting.cjs","names":[],"sources":["../../../src/batteries/tools/formatting/index.ts"],"sourcesContent":["/**\n * Pre-constructed tools for locale-aware number, list, table, and text formatting.\n *\n * @module @nhtio/adk/batteries/tools/formatting\n *\n * @remarks\n * Pre-constructed bundled tools for the `formatting` category. Import individually, the whole\n * category, or import every tool via `@nhtio/adk/batteries`.\n */\n\nimport { Tool } from '@nhtio/adk/common'\nimport { isError } from '@nhtio/adk/guards'\nimport { validator } from '@nhtio/validation'\n\n/**\n * Format a number using locale-aware styles.\n *\n * @remarks\n * Supported styles: `decimal`, `currency`, `percent`, `compact` (e.g. `1.2K`), `scientific`\n * (e.g. `1.2e+3`), and `ordinal` (`1st`, `2nd`, `3rd`). Uses `Intl.NumberFormat` and\n * `Intl.PluralRules` from the JS standard library. Returns an error string for non-finite values\n * or invalid currency-without-currency-code.\n */\nexport const formatNumberTool = new Tool({\n name: 'format_number',\n description:\n 'Format a number using locale-aware styles: decimal, currency, percent, compact (1.2K), scientific (1.2e3), or ordinal (1st/2nd/3rd). Supports locale and precision options.',\n inputSchema: validator.object({\n value: validator.number().required().description('The number to format'),\n style: validator\n .string()\n .valid('decimal', 'currency', 'percent', 'compact', 'scientific', 'ordinal')\n .default('decimal')\n .description('Formatting style (default: decimal)'),\n currency: validator\n .string()\n .optional()\n .description(\n 'ISO 4217 currency code — required when style is \"currency\" (e.g. \"USD\", \"EUR\")'\n ),\n locale: validator.string().default('en-US').description('BCP 47 locale tag (default: \"en-US\")'),\n min_decimals: validator\n .number()\n .optional()\n .description('Minimum fraction digits (default: style-dependent)'),\n max_decimals: validator\n .number()\n .optional()\n .description('Maximum fraction digits (default: style-dependent)'),\n }),\n handler: async (args) => {\n const {\n value,\n style,\n locale,\n currency,\n min_decimals: minDec,\n max_decimals: maxDec,\n } = args as {\n value: number\n style: string\n locale: string\n currency?: string\n min_decimals?: number\n max_decimals?: number\n }\n\n if (!Number.isFinite(value)) return `Error: Value must be a finite number (got ${value}).`\n\n try {\n if (style === 'ordinal') {\n const pr = new Intl.PluralRules(locale, { type: 'ordinal' })\n const suffixes: Record<string, string> = { one: 'st', two: 'nd', few: 'rd', other: 'th' }\n const rule = pr.select(value)\n const suffix = suffixes[rule] ?? 'th'\n return `${new Intl.NumberFormat(locale).format(value)}${suffix}`\n }\n\n if (style === 'scientific') {\n const exp = value === 0 ? 0 : Math.floor(Math.log10(Math.abs(value)))\n const mantissa = value / Math.pow(10, exp)\n const mFormatted = new Intl.NumberFormat(locale, {\n minimumFractionDigits: minDec ?? 2,\n maximumFractionDigits: maxDec ?? 6,\n }).format(mantissa)\n return `${mFormatted}e${exp >= 0 ? '+' : ''}${exp}`\n }\n\n const opts: Intl.NumberFormatOptions = {}\n\n if (style === 'currency') {\n if (!currency) return 'Error: \"currency\" parameter is required when style is \"currency\".'\n opts.style = 'currency'\n opts.currency = currency.toUpperCase()\n } else if (style === 'percent') {\n opts.style = 'percent'\n opts.minimumFractionDigits = minDec ?? 1\n opts.maximumFractionDigits = maxDec ?? 2\n } else if (style === 'compact') {\n opts.notation = 'compact'\n opts.compactDisplay = 'short'\n } else {\n opts.style = 'decimal'\n }\n\n if (minDec !== undefined && style !== 'percent') opts.minimumFractionDigits = minDec\n if (maxDec !== undefined && style !== 'percent') opts.maximumFractionDigits = maxDec\n\n return new Intl.NumberFormat(locale, opts).format(value)\n } catch (err) {\n return `Error: ${isError(err) ? err.message : String(err)}`\n }\n },\n})\n\n/**\n * Format an array of items as a list.\n *\n * @remarks\n * Supported styles: `bullet` (`• item`), `numbered` (`1. item`), `inline_and`\n * (`a, b, and c`), `inline_or` (`a, b, or c`), `newline` (one per line).\n */\nexport const formatListTool = new Tool({\n name: 'format_list',\n description:\n 'Format an array of items as a list. Styles: bullet (• item), numbered (1. item), inline_and (\"a, b, and c\"), inline_or (\"a, b, or c\"), newline (one per line).',\n inputSchema: validator.object({\n items: validator\n .array()\n .items(validator.string())\n .required()\n .description('Array of items to format'),\n style: validator\n .string()\n .valid('bullet', 'numbered', 'inline_and', 'inline_or', 'newline')\n .default('bullet')\n .description('List format style (default: bullet)'),\n indent: validator.number().default(0).description('Spaces to indent each item (default: 0)'),\n }),\n handler: async (args) => {\n const {\n items,\n style,\n indent: rawIndent,\n } = args as {\n items: string[]\n style: string\n indent: number\n }\n // Clamp indent to a sane maximum: an unbounded value reaches `' '.repeat(indent)` and throws\n // RangeError (Invalid string length). 100 spaces is far past any real formatting need.\n const indent = Math.min(100, Math.max(0, Math.floor(rawIndent)))\n const pad = ' '.repeat(indent)\n\n if (items.length === 0) return ''\n\n switch (style) {\n case 'bullet':\n return items.map((item) => `${pad}• ${item}`).join('\\n')\n case 'numbered':\n return items.map((item, i) => `${pad}${i + 1}. ${item}`).join('\\n')\n case 'newline':\n return items.map((item) => `${pad}${item}`).join('\\n')\n case 'inline_and':\n case 'inline_or': {\n const conj = style === 'inline_and' ? 'and' : 'or'\n if (items.length === 1) return items[0]\n if (items.length === 2) return `${items[0]} ${conj} ${items[1]}`\n const last = items[items.length - 1]\n const rest = items.slice(0, -1)\n return `${rest.join(', ')}, ${conj} ${last}`\n }\n default:\n return `Error: Unknown style \"${style}\".`\n }\n },\n})\n"],"mappings":"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"}
|