agent-first-data 0.12.0__tar.gz → 0.12.2__tar.gz
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.
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/PKG-INFO +1 -1
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/agent_first_data/__init__.py +0 -2
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/agent_first_data/afdata_logging.py +0 -4
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/agent_first_data/format.py +26 -6
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/agent_first_data.egg-info/PKG-INFO +1 -1
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/pyproject.toml +1 -1
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/tests/test_afdata_logging.py +5 -5
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/README.md +0 -0
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/agent_first_data/cli.py +0 -0
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/agent_first_data/skill.py +0 -0
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/agent_first_data.egg-info/SOURCES.txt +0 -0
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/agent_first_data.egg-info/dependency_links.txt +0 -0
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/agent_first_data.egg-info/top_level.txt +0 -0
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/setup.cfg +0 -0
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/tests/test_cli.py +0 -0
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/tests/test_format.py +0 -0
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/tests/test_no_stderr_policy.py +0 -0
- {agent_first_data-0.12.0 → agent_first_data-0.12.2}/tests/test_skill.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-first-data
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.2
|
|
4
4
|
Summary: A naming convention that lets AI agents understand your data without being told what it means.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Repository, https://github.com/agentfirstkit/agent-first-data
|
|
@@ -27,7 +27,6 @@ from agent_first_data.format import (
|
|
|
27
27
|
|
|
28
28
|
from agent_first_data.afdata_logging import (
|
|
29
29
|
AfdataHandler,
|
|
30
|
-
AfdataJsonHandler,
|
|
31
30
|
init_json as init_logging_json,
|
|
32
31
|
init_plain as init_logging_plain,
|
|
33
32
|
init_yaml as init_logging_yaml,
|
|
@@ -84,7 +83,6 @@ __all__ = [
|
|
|
84
83
|
"redact_url_secrets_with_options",
|
|
85
84
|
"parse_size",
|
|
86
85
|
"AfdataHandler",
|
|
87
|
-
"AfdataJsonHandler",
|
|
88
86
|
"init_logging_json",
|
|
89
87
|
"init_logging_plain",
|
|
90
88
|
"init_logging_yaml",
|
|
@@ -87,10 +87,6 @@ class AfdataHandler(logging.Handler):
|
|
|
87
87
|
sys.stdout.flush()
|
|
88
88
|
|
|
89
89
|
|
|
90
|
-
# Keep old name as alias for backwards compat
|
|
91
|
-
AfdataJsonHandler = AfdataHandler
|
|
92
|
-
|
|
93
|
-
|
|
94
90
|
class _AfdataLoggerAdapter(logging.LoggerAdapter):
|
|
95
91
|
"""Logger adapter that passes extra fields to AfdataHandler."""
|
|
96
92
|
|
|
@@ -11,7 +11,7 @@ from __future__ import annotations
|
|
|
11
11
|
import json
|
|
12
12
|
import math
|
|
13
13
|
from dataclasses import dataclass, field
|
|
14
|
-
from datetime import datetime, timezone
|
|
14
|
+
from datetime import datetime, timedelta, timezone
|
|
15
15
|
from enum import Enum
|
|
16
16
|
from typing import Any, Sequence
|
|
17
17
|
from urllib.parse import unquote_plus
|
|
@@ -515,9 +515,27 @@ def _is_number(value: Any) -> bool:
|
|
|
515
515
|
return isinstance(value, (int, float)) and not isinstance(value, bool)
|
|
516
516
|
|
|
517
517
|
|
|
518
|
+
def _number_str(value: int | float) -> str:
|
|
519
|
+
"""Render a number canonically for YAML/plain output.
|
|
520
|
+
|
|
521
|
+
An integral-valued float drops its trailing ``.0`` (``3.0`` -> ``3``) so the
|
|
522
|
+
four language implementations stay byte-identical with Go/TS/Rust.
|
|
523
|
+
"""
|
|
524
|
+
if isinstance(value, float) and math.isfinite(value) and value.is_integer():
|
|
525
|
+
return str(int(value))
|
|
526
|
+
return str(value)
|
|
527
|
+
|
|
528
|
+
|
|
518
529
|
def _as_int(value: Any) -> int | None:
|
|
519
|
-
if isinstance(value,
|
|
530
|
+
if isinstance(value, bool):
|
|
531
|
+
return None
|
|
532
|
+
if isinstance(value, int):
|
|
520
533
|
return value
|
|
534
|
+
# Accept integral-valued floats (3.0 -> 3): JS/TS cannot distinguish 3 from
|
|
535
|
+
# 3.0 after JSON parsing, so integrality (not lexical form) gates integer
|
|
536
|
+
# suffixes, keeping the four implementations consistent.
|
|
537
|
+
if isinstance(value, float) and math.isfinite(value) and value.is_integer():
|
|
538
|
+
return int(value)
|
|
521
539
|
return None
|
|
522
540
|
|
|
523
541
|
|
|
@@ -714,10 +732,12 @@ def _format_ms_value(value: Any) -> str | None:
|
|
|
714
732
|
|
|
715
733
|
|
|
716
734
|
def _format_rfc3339_ms(ms: int) -> str:
|
|
735
|
+
# Build from an integer timedelta (not float ms/1000) so large values keep
|
|
736
|
+
# full precision and the second split matches Rust's div_euclid exactly.
|
|
717
737
|
try:
|
|
718
|
-
dt = datetime
|
|
738
|
+
dt = datetime(1970, 1, 1, tzinfo=timezone.utc) + timedelta(milliseconds=ms)
|
|
719
739
|
return dt.strftime("%Y-%m-%dT%H:%M:%S.") + f"{ms % 1000:03d}Z"
|
|
720
|
-
except (
|
|
740
|
+
except (OverflowError, ValueError):
|
|
721
741
|
return str(ms)
|
|
722
742
|
|
|
723
743
|
|
|
@@ -854,7 +874,7 @@ def _yaml_scalar(value: Any) -> str:
|
|
|
854
874
|
if isinstance(value, bool):
|
|
855
875
|
return "true" if value else "false"
|
|
856
876
|
if isinstance(value, (int, float)):
|
|
857
|
-
return
|
|
877
|
+
return _number_str(value)
|
|
858
878
|
escaped = str(value).replace('"', '\\"')
|
|
859
879
|
return f'"{escaped}"'
|
|
860
880
|
|
|
@@ -907,7 +927,7 @@ def _plain_scalar(value: Any) -> str:
|
|
|
907
927
|
if isinstance(value, bool):
|
|
908
928
|
return "true" if value else "false"
|
|
909
929
|
if isinstance(value, (int, float)):
|
|
910
|
-
return
|
|
930
|
+
return _number_str(value)
|
|
911
931
|
return str(value)
|
|
912
932
|
|
|
913
933
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: agent-first-data
|
|
3
|
-
Version: 0.12.
|
|
3
|
+
Version: 0.12.2
|
|
4
4
|
Summary: A naming convention that lets AI agents understand your data without being told what it means.
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
Project-URL: Repository, https://github.com/agentfirstkit/agent-first-data
|
|
@@ -6,7 +6,7 @@ import sys
|
|
|
6
6
|
from io import StringIO
|
|
7
7
|
from unittest.mock import patch
|
|
8
8
|
|
|
9
|
-
from agent_first_data.afdata_logging import AfdataHandler,
|
|
9
|
+
from agent_first_data.afdata_logging import AfdataHandler, init_json, init_plain, init_yaml, span, get_logger
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
def capture_log(fn):
|
|
@@ -20,9 +20,9 @@ def capture_log(fn):
|
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def make_logger(name="test"):
|
|
23
|
-
"""Create a fresh logger with
|
|
23
|
+
"""Create a fresh logger with AfdataHandler."""
|
|
24
24
|
logger = logging.getLogger(name)
|
|
25
|
-
logger.handlers = [
|
|
25
|
+
logger.handlers = [AfdataHandler()]
|
|
26
26
|
logger.setLevel(logging.DEBUG)
|
|
27
27
|
return logger
|
|
28
28
|
|
|
@@ -121,9 +121,9 @@ class TestCodeOverride:
|
|
|
121
121
|
|
|
122
122
|
class TestGetLogger:
|
|
123
123
|
def test_default_fields(self):
|
|
124
|
-
# Ensure root logger has
|
|
124
|
+
# Ensure root logger has AfdataHandler
|
|
125
125
|
root = logging.getLogger()
|
|
126
|
-
root.handlers = [
|
|
126
|
+
root.handlers = [AfdataHandler()]
|
|
127
127
|
root.setLevel(logging.DEBUG)
|
|
128
128
|
|
|
129
129
|
adapter = get_logger("test_adapter", component="myservice")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{agent_first_data-0.12.0 → agent_first_data-0.12.2}/agent_first_data.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|