* feat: support timestamp="unset" to retain content without a date When callers retain timeless content (e.g. fictional documents, static reference material), passing timestamp="unset" now skips the utcnow() default so mentioned_at is stored as NULL instead of an artificial date. - HTTP: validate_timestamp recognises "unset" sentinel and threads it through api_retain as event_date=None (key present, value None), which the orchestrator distinguishes from key-absent (still defaults to now) - Orchestrator: new branching logic separates "key absent" → utcnow() from "key present but None" → no date - types.py: RetainContent.event_date and ProcessedFact.mentioned_at are now datetime | None; removed the unused _now_utc factory - fact_extraction.py: all event_date params accept datetime | None; _build_user_message emits "Event Date: Unknown" when None; removed mentioned_at from the Fact LLM response model (LLM never sets it) - embedding_processing: skip date suffix when fact_date is None - entity_resolver: COALESCE(event_date, now()) for first_seen/last_seen so entities table NOT NULL constraint is preserved - link_utils: skip temporal linking for units without event_date - Migration aa2b3c4d5e6f: DROP NOT NULL on memory_units.event_date - Tests: test_retain_no_timestamp and test_retain_omit_timestamp_defaults_to_now - Docs + OpenAPI + TypeScript client updated * refactor: replace _TIMESTAMP_UNKNOWN sentinel with plain string comparison The sentinel object() was only needed to distinguish "unset" from None at the boundary — but since the field type is datetime | str | None, "unset" can pass through the validator unchanged and be compared directly. * chore: regenerate OpenAPI spec and clients after timestamp type change timestamp field is now datetime | str | None to accept the "unset" sentinel value.
113 lines
2.5 KiB
Go
113 lines
2.5 KiB
Go
/*
|
|
Hindsight HTTP API
|
|
|
|
HTTP API for Hindsight
|
|
|
|
API version: 0.4.14
|
|
*/
|
|
|
|
// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT.
|
|
|
|
package hindsight
|
|
|
|
import (
|
|
"encoding/json"
|
|
"time"
|
|
"fmt"
|
|
)
|
|
|
|
|
|
// Timestamp When the content occurred. Accepts an ISO 8601 datetime string (e.g. '2024-01-15T10:30:00Z'), null/omitted (defaults to now), or the special string 'unset' to explicitly store without any timestamp (use this for timeless content such as fictional documents or static reference material).
|
|
type Timestamp struct {
|
|
String *string
|
|
TimeTime *time.Time
|
|
}
|
|
|
|
// Unmarshal JSON data into any of the pointers in the struct
|
|
func (dst *Timestamp) UnmarshalJSON(data []byte) error {
|
|
var err error
|
|
// this object is nullable so check if the payload is null or empty string
|
|
if string(data) == "" || string(data) == "{}" {
|
|
return nil
|
|
}
|
|
|
|
// try to unmarshal JSON data into String
|
|
err = json.Unmarshal(data, &dst.String);
|
|
if err == nil {
|
|
jsonString, _ := json.Marshal(dst.String)
|
|
if string(jsonString) == "{}" { // empty struct
|
|
dst.String = nil
|
|
} else {
|
|
return nil // data stored in dst.String, return on the first match
|
|
}
|
|
} else {
|
|
dst.String = nil
|
|
}
|
|
|
|
// try to unmarshal JSON data into TimeTime
|
|
err = json.Unmarshal(data, &dst.TimeTime);
|
|
if err == nil {
|
|
jsonTimeTime, _ := json.Marshal(dst.TimeTime)
|
|
if string(jsonTimeTime) == "{}" { // empty struct
|
|
dst.TimeTime = nil
|
|
} else {
|
|
return nil // data stored in dst.TimeTime, return on the first match
|
|
}
|
|
} else {
|
|
dst.TimeTime = nil
|
|
}
|
|
|
|
return fmt.Errorf("data failed to match schemas in anyOf(Timestamp)")
|
|
}
|
|
|
|
// Marshal data from the first non-nil pointers in the struct to JSON
|
|
func (src *Timestamp) MarshalJSON() ([]byte, error) {
|
|
if src.String != nil {
|
|
return json.Marshal(&src.String)
|
|
}
|
|
|
|
if src.TimeTime != nil {
|
|
return json.Marshal(&src.TimeTime)
|
|
}
|
|
|
|
return nil, nil // no data in anyOf schemas
|
|
}
|
|
|
|
|
|
type NullableTimestamp struct {
|
|
value *Timestamp
|
|
isSet bool
|
|
}
|
|
|
|
func (v NullableTimestamp) Get() *Timestamp {
|
|
return v.value
|
|
}
|
|
|
|
func (v *NullableTimestamp) Set(val *Timestamp) {
|
|
v.value = val
|
|
v.isSet = true
|
|
}
|
|
|
|
func (v NullableTimestamp) IsSet() bool {
|
|
return v.isSet
|
|
}
|
|
|
|
func (v *NullableTimestamp) Unset() {
|
|
v.value = nil
|
|
v.isSet = false
|
|
}
|
|
|
|
func NewNullableTimestamp(val *Timestamp) *NullableTimestamp {
|
|
return &NullableTimestamp{value: val, isSet: true}
|
|
}
|
|
|
|
func (v NullableTimestamp) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(v.value)
|
|
}
|
|
|
|
func (v *NullableTimestamp) UnmarshalJSON(src []byte) error {
|
|
v.isSet = true
|
|
return json.Unmarshal(src, &v.value)
|
|
}
|
|
|
|
|