
    $jH             	          d Z ddlZddlZddlZddlZddlZddlmZ ddlmZm	Z	 ddl
mZmZ ddlmZmZmZmZmZmZmZmZmZ ddlmZmZ ddlmZ d	ed
eeef         fdZddl
mZ ddl m!Z!m"Z"m#Z#m$Z$m%Z% ddl&m'Z' ded
efdZ(ddl)m*Z* ddl+m,Z,m-Z-m.Z.m/Z/ ddl0m1Z1 ddl2m3Z3m4Z4m5Z5 ddl6m7Z7m8Z8 ddlm9Z9m:Z:m;Z; ddl<m=Z=m>Z>m?Z? ddl@mAZA  ejB        eC          ZD G d de!          ZE G d de!          ZF G d de!          ZG G d d e!          ZH G d! d"e!          ZI G d# d$e!          ZJ G d% d&e!          ZK G d' d(e!          ZL G d) d*e!          ZM G d+ d,e!          ZN G d- d.e!          ZO G d/ d0e!          ZP G d1 d2e!          ZQ G d3 d4e!          ZR G d5 d6e!          ZS G d7 d8e!          ZT G d9 d:e!          ZU G d; d<e!          ZV G d= d>e!          ZW G d? d@e!          ZX G dA dBe!          ZY G dC dDe!          ZZ G dE dFe!          Z[ G dG dHe!          Z\ G dI dJe!          Z] G dK dLe!          Z^ G dM dNe!          Z_ G dO dPe!          Z` G dQ dRe!          Za G dS dTe!          Zb G dU dVe!          Zc G dW dXe!          Zd G dY dZe!          Ze G d[ d\e!          Zf G d] d^e!          Zg G d_ d`e!          Zh G da dbe!          Zi G dc dde!          Zj G de dfe!          Zk G dg dhe!          Zl G di dje!          Zm G dk dle!          Zn G dm dne!          Zo G do dpe!          Zp G dq dre!          Zq G ds dte!          Zr G du dve!          Zs G dw dxe!          Zt G dy dze!          Zu G d{ d|e!          Zv G d} d~e!          Zw G d de!          Zx G d de!          Zy G d de!          Zz G d de!          Z{ G d de!          Z| G d de!          Z} G d de!          Z~ G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          ZdZ G d de!          Z G d de!          Z G d de!          Z G d de!          Z G d de!          Zddd
ee         fdZdeddddd
dfdZ G d de!          Z G d de!          Z G d de!          Z G d de!          Z G dĄ de!          Z G dƄ de!          Z G dȄ de!          Z G dʄ de!          Z G d̄ de!          Z G d΄ de!          ZddlmZ  G dф de!          Z G dӄ de!          Z G dՄ de!          Z G dׄ de!          Z G dل de!          Z G dۄ de!          Zdeg edz  f         fdބZ	 	 dde'dede9dz  d
efdZdefdZdS )z
FastAPI application factory and API routes for memory system.

This module provides the create_app function to create and configure
the FastAPI application with all API endpoints.
    N)asynccontextmanager)datetimetimezone)AnyLiteral)	DependsFastAPIFileFormHeaderHTTPExceptionQueryRequest
UploadFile)
AuditEntryAuditLogger)AuthenticationErrormetadatareturnc                     | i S t          | t                    r| S t          | t                    r,	 t          j        |           S # t          j        $ r i cY S w xY wi S )z8Parse metadata that may be a dict, JSON string, or None.)
isinstancedictstrjsonloadsJSONDecodeError)r   s    ^/home/rurouni/.hermes/hermes-agent/venv/lib/python3.11/site-packages/hindsight_api/api/http.py_parse_metadatar      sw    	(D!! (C   	:h'''# 	 	 	III	Is   A AACallable)	BaseModel
ConfigDictFieldfield_validatormodel_validator)MemoryEnginedefault_factoryc                     | t           u rg }n| t          u ri }ni }|                    di           }t          |t                    r||d<   nd|i}t	          d| |d|S )aj  
    Field wrapper that ensures default_factory values appear in OpenAPI schema.

    Pydantic doesn't include default_factory in OpenAPI schemas, causing OpenAPI
    Generator to make fields Optional with default=None instead of non-optional
    with the correct default value.

    This wrapper adds json_schema_extra to include the default in the schema.
    json_schema_extradefault)r'   r)    )listr   popr   r#   )r'   kwargsschema_default
json_extras       r   FieldWithDefaultr1   ,   s     $	D	 	   /44J*d## 1 .
9  0
YJYYRXYYY    
get_config)Budget_current_schema_get_tiktoken_encodingfq_table)LLMNotAvailableError)VALID_RECALL_FACT_TYPES
MemoryFact
TokenUsage)TagGroup	TagsMatch)HttpExtensionOperationValidationErrorload_extension)create_metrics_collectorget_metrics_collectorinitialize_metrics)RequestContextc                   8    e Zd ZU dZ edd          Zeed<   dS )EntityIncludeOptionsz<Options for including entity observations in recall results.  z&Maximum tokens for entity observationsr*   description
max_tokensN__name__
__module____qualname____doc__r#   rK   int__annotations__r+   r2   r   rG   rG   W   s8         FFeC5]^^^J^^^^^r2   rG   c                   8    e Zd ZU dZ edd          Zeed<   dS )ChunkIncludeOptionsz/Options for including chunks in recall results.    z3Maximum tokens for chunks (chunks may be truncated)rI   rK   NrL   r+   r2   r   rT   rT   ]   s8         99eD6klllJlllllr2   rT   c                   \    e Zd ZU dZ edd          Zeed<    edd          Zeed<   d	S )
SourceFactsIncludeOptionsz@Options for including source facts for observation-type results.   zNMaximum total tokens for source facts across all observations (-1 = unlimited)rI   rK   z?Maximum tokens of source facts per observation (-1 = unlimited)max_tokens_per_observationN)	rM   rN   rO   rP   r#   rK   rQ   rR   rZ   r+   r2   r   rW   rW   c   sy         JJe"r  J    ',e a' ' '     r2   rW   c                       e Zd ZU dZ e e            d          Zedz  ed<    edd          Ze	dz  ed<    edd          Z
edz  ed	<   dS )
IncludeOptionsz8Options for including additional data in recall results.zEInclude entity observations. Set to null to disable entity inclusion.rI   NentitieszMInclude raw chunks. Set to {} to enable, null to disable (default: disabled).chunkszlInclude source facts for observation-type results. Set to {} to enable, null to disable (default: disabled).source_facts)rM   rN   rO   rP   r#   rG   r]   rR   r^   rT   r_   rW   r+   r2   r   r\   r\   n   s         BB,1E$$&&[- - -H"T)    */"q* * *F$&    6;U C6 6 6L+d2     r2   r\   c                      e Zd ZU dZ eddddgdddd	d
ddiidgdd	i          Zeed<    edd          Z	e
e         dz  ed<   ej        Zeed<   dZeed<   dZeed<    edd          Zedz  ed<    eed          Zeed<    edd          Ze
e         dz  ed<    edd           Zeed!<    edd"          Ze
e         dz  ed#<    ed          ed$ed%efd&                        Z ed'(          d*d)            ZdS )+RecallRequestz"Request model for recall endpoint.example*What did Alice say about machine learning?world
experiencemidrX   Tz2023-05-30T23:40:00r]   rK   rH   user_aany)	querytypesbudgetrK   tracequery_timestampincludetags
tags_matchr)   ri   NzvList of fact types to recall: 'world', 'experience', 'observation'. Defaults to world and experience if not specified.rI   rj   rk   Frl   z4ISO format date string (e.g., '2023-05-30T23:40:00')rm   zHOptions for including additional data (entities are included by default)rJ   rn   zEFilter memories by tags. If not specified, all memories are returned.ro   How to match tags: 'any' (OR, includes untagged), 'all' (AND, includes untagged), 'any_strict' (OR, excludes untagged), 'all_strict' (AND, excludes untagged).rp   Compound tag filter using boolean groups. Groups in the list are AND-ed. Each group is a leaf {tags, match} or compound {and: [...]}, {or: [...]}, {not: ...}.
tag_groupsvr   c                 F    ddl m}  ||          st          d          |S )N   )tokenize_queryzBquery must contain at least one word character after normalization)engine.search.retrievalry   
ValueError)clsrv   ry   s      r   validate_query_not_emptyz&RecallRequest.validate_query_not_empty   s=     	=<<<<<~a   	cabbbr2   aftermodec                 @    | j         | j        t          d          | S NzX'tags' and 'tag_groups' are mutually exclusive. Use 'tag_groups' for compound filtering.ro   ru   r{   selfs    r   validate_tags_exclusivez%RecallRequest.validate_tags_exclusive   %    9 T_%@wxxxr2   )r   ra   ) rM   rN   rO   rP   r"   model_configr   rR   r#   rj   r,   r5   MIDrk   rK   rQ   rl   boolrm   r1   r\   rn   ro   rp   r>   ru   r=   r$   classmethodr}   r%   r   r+   r2   r   ra   ra   ~   s_        ,,:E!<0"#8&s(;<!
#
 

  L  JJJ#e M  E49t    ZFFJE4"'%"X# # #OS4Z    /.^  G^    #U[  D$s)d
    "EW  J	   
 ).`) ) )JX%    _W     [  _'"""   #"  r2   ra   c                   l   e Zd ZU dZdddddddgd	d
d
d
dddidddgdidZeed<   eed<   dZedz  ed<   dZe	e         dz  ed<   dZ
edz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   dZeeef         dz  ed<   dZedz  ed<   dZe	e         dz  ed<   dZe	e         dz  ed <   dS )!RecallResultzSingle recall result item.Trb   $123e4567-e89b-12d3-a456-426614174000$Alice works at Google on the AI teamrd   AliceGoogle	work info2024-01-15T10:30:00Zsession_abc123sourceslack$456e7890-e12b-34d5-a678-901234567890rg   user_b)idtexttyper]   contextoccurred_startoccurred_endmentioned_atdocument_idr   chunk_idro   populate_by_namer)   r   r   Nr   r]   r   r   r   r   r   r   r   ro   source_fact_ids)rM   rN   rO   rP   r   r   rR   r   r]   r,   r   r   r   r   r   r   r   r   ro   r   r+   r2   r   r   r      s        $$ !<>$h/&"8 6 6/%w/B!8, 
 L( 	GGG
IIID#*!%Hd3i$%%%GS4Z!%NC$J%%%#L#*####L#*###"Kt"""&*Hd38nt#***HcDj!D$s)d
!!! T#Y%     r2   r   c                   2    e Zd ZU dZeed<   dZedz  ed<   dS )EntityObservationResponsezAn observation about an entity.r   Nr   )rM   rN   rO   rP   r   rR   r   r+   r2   r   r   r      s5         ))
III#L#*#####r2   r   c                   >    e Zd ZU dZeed<   eed<   ee         ed<   dS )EntityStateResponsez"Current mental model of an entity.	entity_idcanonical_nameobservationsN)rM   rN   rO   rP   r   rR   r,   r   r+   r2   r   r   r      s?         ,,NNN0111111r2   r   c            	           e Zd ZU dZ edddddddi	          Zeed
<   eed<   eed<   dZ	edz  ed<   dZ
edz  ed<   dZeeef         dz  ed<   dS )EntityListItemzEntity list item with summary.rb   r   John   r   2024-02-01T14:00:00Zr   r   mention_count
first_seen	last_seenrq   r   r   r   Nr   r   r   )rM   rN   rO   rP   r"   r   r   rR   rQ   r   r   r   r   r   r+   r2   r   r   r      s         ((:<"(!#43 

 
 
L 	GGG!Jd
!!! IsTz   &*Hd38nt#*****r2   r   c            	       |    e Zd ZU dZ edddddddgd	d
ddi          Zee         ed<   e	ed<   e	ed<   e	ed<   dS )EntityListResponsez(Response model for entity list endpoint.rb   r   r   r   r   r   r      d   r   itemstotallimitoffsetrq   r   r   r   r   N)
rM   rN   rO   rP   r"   r   r,   r   rR   rQ   r+   r2   r   r   r     s         22: E*0)+&<%;   
  L& JJJJJJKKKKKr2   r   c                       e Zd ZU dZ edddddddidd	d
dddigdddd	ddddddigddddi          Zeeee	f                  e
d<   eeee	f                  e
d<   ee
d<   ee
d<   ee
d<   dS )EntityGraphResponsez7Response model for entity co-occurrence graph endpoint.rb   datazuuid-1r      z#42a5f5)r   labelmentionCountcolorzuuid-2r      zuuid-1-uuid-2cooccurrence   z#ffd700solidr   )r   r   targetlinkTypeweightr   	lineStylelastCooccurredrx        )nodesedgestotal_entitiestotal_edgesr   rq   r   r   r   r   r   NrM   rN   rO   rP   r"   r   r,   r   r   r   rR   rQ   r+   r2   r   r   r   )  s         AA:HwPR]fgghHxQR]fggh "1&.&.(6&'%.)0.D	! 	! #$ + 
  L8 S#XS#XJJJJJr2   r   c                       e Zd ZU dZ eddddddddd	gd
i          Zeed<   eed<   eed<   dZ	edz  ed<   dZ
edz  ed<   dZeeef         dz  ed<   ee         ed<   dS )EntityDetailResponsez*Response model for entity detail endpoint.rb   r   r   r   r   r   zJohn works at Googler   r   )r   r   r   r   r   r   rq   r   r   r   Nr   r   r   r   )rM   rN   rO   rP   r"   r   r   rR   rQ   r   r   r   r   r   r,   r   r+   r2   r   r   r   O  s         44:<"(!#43*@Rh!i!i j 	
  L 	GGG!Jd
!!! IsTz   &*Hd38nt#***0111111r2   r   c                   V    e Zd ZU dZeed<   eed<   eed<    edd          Ze	ed<   d	S )
	ChunkDatazChunk data for a single chunk.r   r   chunk_indexFz8Whether the chunk text was truncated due to token limitsrI   	truncatedN)
rM   rN   rO   rP   r   rR   rQ   r#   r   r   r+   r2   r   r   r   h  sV         ((GGG
IIIeE7qrrrItrrrrrr2   r   c                   b   e Zd ZU dZ eddddddgdd	d	d
dgddddddddd	dgdid
d
dddidi          Zee         ed<   dZ	e
eef         dz  ed<    edd          Ze
eef         dz  ed<    edd          Ze
eef         dz  ed<    edd           Ze
eef         dz  ed!<   dS )"RecallResponsez$Response model for recall endpoints.rb   r   r   rd   r   r   r   r   r   )r   r   r   r]   r   r   r   r   rc   r   grh|?)ri   num_resultstime_secondsz$123e4567-e89b-12d3-a456-426614174001r   r   r   r   zEAlice works at Google on the AI team. She's been there for 3 years...r   )r   r   r   )resultsrl   r]   r^   rq   r   Nrl   z/Entity states for entities mentioned in resultsrI   r]   z#Chunks for facts, keyed by chunk_idr^   z;Source facts for observation-type results, keyed by fact IDr_   )rM   rN   rO   rP   r"   r   r,   r   rR   rl   r   r   r   r#   r]   r   r^   r   r_   r+   r2   r   r   r   q  s        ..: E F '%,h$7#.*@(>$J	 	 J#$$)  %K*1%K]stt)  ;D g'(= =7" "$
& & &LP ,#'E4S>D '''6;e"S7 7 7Hd3++,t3    +0%Jo*p*p*pFDi 4'ppp385"_4 4 4L$sL()D0     r2   r   c                   `    e Zd ZU dZ ed          Zeed<    edd          Zedz  ed<   dS )	EntityInputz*Entity to associate with retained content.zThe entity name/textrr   r   Nz7Optional entity type (e.g., 'PERSON', 'ORG', 'CONCEPT')rI   r   )	rM   rN   rO   rP   r#   r   r   rR   r   r+   r2   r   r   r     sZ         44"8999D#999uT7pqqqD#*qqqqqr2   r   c                      e Zd ZU dZ edddddddd	d
didddgddgdi          Zeed<    edd          Z	e
ez  dz  ed<   dZedz  ed<   dZeeef         dz  ed<    edd          Zedz  ed<    edd          Zee         dz  ed<    edd          Zee         dz  ed<    edd !          ed"                         Z edd#d$%          Zed&         eee                  z  dz  ed'<    edd(          Zedz  ed)<    edd*          Zed+         dz  ed,<    edd !          ed-                         ZdS ).
MemoryItemzSingle memory item for retain.rb   z/Alice mentioned she's working on a new ML modelr   zteam meetingr   engineeringr   channelmeeting_notes_2024_01_15r   r   zML modelCONCEPTr   r   rg   r   )content	timestampr   r   r   r]   ro   rq   r   Na  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).rI   r   r   r   z*Optional document ID for this memory item.r   z:Optional entities to combine with auto-extracted entities.r]   zWOptional tags for visibility scoping. Memories with tags can be filtered during recall.ro   beforer   c                     t          |t                    rL	 t          j        |          }t          |t                    r|S n# t          j        t          f$ r Y nw xY w|gS |S )aN  Coerce JSON-string tags to list.

        MCP tool bridges sometimes serialize JSON arrays as strings during
        transport, e.g. '["a", "b"]' instead of ["a", "b"]. This validator
        parses such strings back into lists so the retain call succeeds.
        A plain non-JSON string is wrapped in a single-element list.
        )r   r   r   r   r,   r   	TypeError)r|   rv   parseds      r   coerce_tagszMemoryItem.coerce_tags  sx     a 	Afd++ "!M"()4   3Js   *A AAObservationScopesa<  How to scope observations during consolidation. 'per_tag' runs one consolidation pass per individual tag, creating separate observations for each tag. 'combined' (default) runs a single pass with all tags together. A list of tag lists runs one pass per inner list, giving full control over which combinations to use.)r*   titlerJ   )per_tagcombinedall_combinationsobservation_scopeszNamed retain strategy for this item. Overrides the bank's default strategy for this item only. Strategies are defined in the bank config under 'retain_strategies'.strategyzHow to handle an existing document with the same document_id. 'replace' (default) deletes old data and reprocesses from scratch. 'append' concatenates new content to the existing document text and reprocesses.)replaceappendupdate_modec                    ||dk    rd S t          |t                    r|S t          |t                    ri|                                dk    rdS 	 t          j        |                    dd                    S # t          $ r}t          d| d          |d }~ww xY wt          dt          |          j                   )N unsetZ+00:00z&Invalid timestamp/event_date format: 'z'. Expected ISO format like '2024-01-15T10:30:00' or '2024-01-15T10:30:00Z', or the special value 'unset' to store without a timestamp.z,timestamp must be a string or datetime, got )	r   r   r   lowerfromisoformatr   r{   r   rM   )r|   rv   es      r   validate_timestampzMemoryItem.validate_timestamp  s     9R4a"" 	Ha 		wwyyG##w-aiiX.F.FGGG     HQ  H  H  H  ZQHXZZ[[[s   'A: :
BBB)rM   rN   rO   rP   r"   r   r   rR   r#   r   r   r   r   r   r   r]   r,   r   ro   r$   r   r   r   r   r   r   r  r+   r2   r   r   r     s        ((:L3)'.=II9$g.Y0W0WX!8, 

  L LLL',uh( ( (Ix#~$    GS4Z&*Hd38nt#***#eD>jkkkKtkkk).P* * *Hd;$&    #Um  D$s)d
   
 _V(+++  [ ,+$ glfk!t		g 	g 	g IJTRVWZR[_\_cc 	 	 	 !5O  HcDj   
 8=u[8 8 8K,-4    _[x000\ \ [ 10\ \ \r2   r   c                       e Zd ZU dZ eddddddddd	gd
di          Zee         ed<    e	d
dd          Z
eed<    e	ddd          Zee         dz  ed<   dS )RetainRequestz"Request model for retain endpoint.rb   Alice works at Googleworkconversation_123)r   r   r   zBob went hiking yesterdayz2024-01-15T10:00:00Z)r   r   r   F)r   asyncrq   r   r  z]If true, process asynchronously in background. If false, wait for completion (default: false))r*   aliasrJ   async_Nz(Deprecated. Use item-level tags instead.Tr*   rJ   
deprecateddocument_tags)rM   rN   rO   rP   r"   r   r,   r   rR   r#   r  r   r  r   r+   r2   r   r  r    s         ,,: 7F[mnn#>%;'9  
 

  L  
5s  FD   
 ',e>' ' 'M49t#     r2   r  c                   h   e Zd ZU dZ edd          Zedz  ed<    edd          Zedz  ed<    edd          Z	e
eef         dz  ed	<    edd
          Zee         dz  ed<    edd          Zedz  ed<    edd          Zeee         z  dz  ed<    edd          Zedz  ed<   dS )FileRetainMetadataz2Metadata for a single file in file retain request.Nz,Document ID (auto-generated if not provided)rI   r   zContext for the filer   zAdditional metadatar   zTags for this filero   zISO timestampr   zwParser or ordered fallback chain for this file (overrides request-level parser). E.g. 'iris' or ['iris', 'markitdown'].parserzNamed retain strategy for this file. Overrides the bank's default strategy. Strategies are defined in the bank config under 'retain_strategies'.r   )rM   rN   rO   rP   r#   r   r   rR   r   r   r   r   ro   r,   r   r  r   r+   r2   r   r  r  3  sO        <<#eD>lmmmKtmmm%:PQQQGS4ZQQQ&+eDF[&\&\&\Hd38nt#\\\"U4=QRRRD$s)d
RRR!E$OLLLIsTzLLL%*U1& & &FC$s)Od"   
 !5O  HcDj     r2   r  c                       e Zd ZU dZ eddddgddddgd	gd
i          Z edd          Zee	e         z  dz  e
d<    edd          Ze	e         dz  e
d<   dS )FileRetainRequestz'Request model for file retain endpoint.rb   irisreport_2024	quarterly)r   ro   zmeeting notes
markitdown)r   r  )r  files_metadatarq   NzDefault parser or ordered fallback chain for all files in this request. E.g. 'markitdown' or ['iris', 'markitdown']. Falls back to server default if not set. Per-file 'parser' in files_metadata takes precedence over this value.rI   r  zIMetadata for each file (optional, must match number of files if provided)r  )rM   rN   rO   rP   r"   r   r#   r  r   r,   rR   r  r  r+   r2   r   r  r  G  s         11: $1K=II /FL;QRR# 

 
 
L &+UP& & &FC$s)Od"    7<e_7 7 7ND+,t3     r2   r  c                      e Zd ZU dZ eddddddddd	d
di          Zeed<   eed<   e	ed<    e
ddd          Zeed<    e
dd          Zedz  ed<    e
dd          Zee         dz  ed<    e
dd          Zedz  ed<   dS )RetainResponsez#Response model for retain endpoint.Trb   user123rx   FrH   r   iX  input_tokensoutput_tokenstotal_tokenssuccessbank_iditems_countr  usager   r#  r$  r%  r  z2Whether the operation was processed asynchronously)r  serialization_aliasrJ   is_asyncNzOperation ID for tracking async operations. Use GET /v1/default/banks/{bank_id}/operations to list operations. Only present when async=true. When items use different per-item strategies, use operation_ids instead.rI   operation_idzOperation IDs when items were submitted as multiple strategy groups (async=true with mixed per-item strategies). operation_id is set to the first entry for backward compatibility.operation_idszbToken usage metrics for LLM calls during fact extraction (only present for synchronous operations)r&  )rM   rN   rO   rP   r"   r   r   rR   r   rQ   r#   r(  r)  r*  r,   r&  r<   r+   r2   r   r  r  b  sU        --:$ *-UXYY 
  L MMMLLLU7@t  Hd     %u l     L#*    ',e J' ' 'M49t#     %ux     E:     r2   r  c                   f    e Zd ZU dZ eddg dii          Z ed          Zee	         e
d<   dS )	FileRetainResponsez(Response model for file upload endpoint.rb   r*  )$550e8400-e29b-41d4-a716-446655440000z$550e8400-e29b-41d4-a716-446655440001z$550e8400-e29b-41d4-a716-446655440002rq   zyOperation IDs for tracking file conversion operations. Use GET /v1/default/banks/{bank_id}/operations to list operations.rr   N)rM   rN   rO   rP   r"   r   r#   r*  r,   r   rR   r+   r2   r   r,  r,    s         22: " " "

 
 
L  %u P     M49     r2   r,  c                       e Zd ZdZdS )FactsIncludeOptionsz:Options for including facts (based_on) in reflect results.N)rM   rN   rO   rP   r+   r2   r   r/  r/    s        DDDr2   r/  c                   8    e Zd ZU dZ edd          Zeed<   dS )ToolCallsIncludeOptionsz4Options for including tool calls in reflect results.TzYInclude tool outputs in the trace. Set to false to only include inputs (smaller payload).rI   outputN)rM   rN   rO   rP   r#   r2  r   rR   r+   r2   r   r1  r1    sI         >>5o  FD     r2   r1  c                   h    e Zd ZU dZ edd          Zedz  ed<    edd          Ze	dz  ed<   dS )ReflectIncludeOptionsz9Options for including additional data in reflect results.NzdInclude facts that the answer is based on. Set to {} to enable, null to disable (default: disabled).rI   factszcInclude tool calls trace. Set to {} for full trace (input+output), {output: false} for inputs only.
tool_calls)
rM   rN   rO   rP   r#   r5  r/  rR   r6  r1  r+   r2   r   r4  r4    s         CC(-z) ) )E%    27y2 2 2J'$.     r2   r4  c                      e Zd ZU dZ edddddi iddd	id
dd	iddddgddgddi          Zeed<   ej	        Z
eed<    eddd          Zedz  ed<    edd          Zeed<    eed          Zeed <    edd!          Zedz  ed"<    edd#          Zee         dz  ed$<    edd%          Zeed&<    edd'          Zee         dz  ed(<    edd)          Zeed*                  dz  ed+<    ed,d-          Zeed.<    edd/          Zee         dz  ed0<    ed+          ed1ee         dz  d2ee         dz  fd3                        Z  e!d45          d7d6            Z"dS )8ReflectRequestz#Request model for reflect endpoint.rb   z0What do you think about artificial intelligence?lowrX   r5  objectr   stringarray)r   r   summary
key_pointsr>  r?  )r   
propertiesrequiredrg   rh   )ri   rk   rK   rn   response_schemaro   rp   rq   ri   rk   NzDEPRECATED: Additional context is now concatenated with the query. Pass context directly in the query field instead. If provided, it will be appended to the query for backward compatibility.Tr  r   zMaximum tokens for the responserI   rK   z;Options for including additional data (disabled by default)r'   rJ   rn   zOptional JSON Schema for structured output. When provided, the response will include a 'structured_output' field with the LLM response parsed according to this schema.rB  zYFilter memories by tags during reflection. If not specified, all memories are considered.ro   rs   rp   rt   ru   lFilter which fact types are retrieved during reflect. None means all types (world, experience, observation).rd   re   observation
fact_typesFZIf true, exclude all mental models from the reflect loop (skip search_mental_models tool).exclude_mental_models;Exclude specific mental models by ID from the reflect loop.exclude_mental_model_idsrv   r   c                 N    |"t          |          dk    rt          d          |S Nr   zAfact_types must not be empty. Use null to include all fact types.lenr{   r|   rv   s     r   validate_reflect_fact_typesz*ReflectRequest.validate_reflect_fact_types  +     =SVVq[[`aaar2   r~   r   c                 @    | j         | j        t          d          | S r   r   r   s    r   r   z&ReflectRequest.validate_tags_exclusive  r   r2   )r   r8  )#rM   rN   rO   rP   r"   r   r   rR   r5   LOWrk   r#   r   rK   rQ   r4  rn   rB  r   ro   r,   rp   r>   ru   r=   rG  r   rI  r   rK  r$   r   rQ  r%   r   r+   r2   r   r8  r8    sK        --:K"#R=$$*H#5/6&(AS&T&T# # "+L 9$ $ "
# 
  L* JJJZFF%T   GS4Z    eD6WXXXJXXX%*U-;x& & &G"    $)5 ~$ $ $OTD[    #Uo  D$s)d
    "EW  J	   
 ).`) ) )JX%   
 NSU CN N NJWABCdJ    #(%p# # #4    27Q2 2 2d3i$.   
 _\""DI,< cTAQ    [ #"
 _'"""   #"  r2   r8  c            
           e Zd ZU dZ eddddddddi	          Zd
Zed
z  ed<    e	d          Z
eed<   d
Zed
z  ed<   d
Zed
z  ed<   d
Zed
z  ed<   d
Zed
z  ed<   d
S )ReflectFactzA fact used in think response.rb   r   AI is used in healthcarerd   zhealthcare discussionr   r   r   r   r   r   r   rq   Nr   z[Fact text. When type='observation', this contains markdown-formatted consolidated knowledgerr   r   r   r   r   r   )rM   rN   rO   rP   r"   r   r   r   rR   r#   r   r   r   r   r   r+   r2   r   rV  rV    s         ((:<22"8 6 	
  L Bd
q  D#    D#*GS4Z!%NC$J%%%#L#*#####r2   rV  c                   z    e Zd ZU dZ ed          Zeed<    ed          Zeed<    ed          Z	eed<   d	S )
ReflectDirectivez#A directive applied during reflect.zDirective IDrr   r   zDirective namenamezDirective contentr   N)
rM   rN   rO   rP   r#   r   r   rR   r[  r   r+   r2   r   rZ  rZ  "  sq         --e///B///"2333D#3335%8999GS99999r2   rZ  c                       e Zd ZU dZ ed          Zeed<    ed          Zeed<    edd	          Z	edz  ed
<   dS )ReflectMentalModelz#A mental model used during reflect.zMental model IDrr   r   zMental model contentr   NzAdditional contextrI   r   )
rM   rN   rO   rP   r#   r   r   rR   r   r   r+   r2   r   r]  r]  *  sx         --e 1222B222"8999D#999%:NOOOGS4ZOOOOOr2   r]  c                       e Zd ZU dZ ed          Zeed<    ed          Ze	ed<    edd	          Z
e	dz  ed
<    ed          Zeed<    edd	          Zeed<   dS )ReflectToolCallz0A tool call made during reflect agent execution.z(Tool name: lookup, recall, learn, expandrr   toolzTool input parametersinputNzBTool output (only included when include.tool_calls.output is true)rI   r2  Execution time in millisecondsduration_msr   z4Iteration number (1-based) when this tool was called	iteration)rM   rN   rO   rP   r#   r`  r   rR   ra  r   r2  rc  rQ   rd  r+   r2   r   r_  r_  2  s         ::"LMMMD#MMM%$;<<<E4<<<%"f  FD4K    u)IJJJKJJJU12hiiiIsiiiiir2   r_  c                   X    e Zd ZU dZ ed          Zeed<    ed          Ze	ed<   dS )ReflectLLMCallz0An LLM call made during reflect agent execution.z)Call scope: agent_1, agent_2, final, etc.rr   scoperb  rc  N)
rM   rN   rO   rP   r#   rg  r   rR   rc  rQ   r+   r2   r   rf  rf  >  sT         ::#NOOOE3OOOu)IJJJKJJJJJr2   rf  c                       e Zd ZU dZ eed          Zee         ed<    eed          Z	ee
         ed<    eed          Zee         ed<   d	S )
ReflectBasedOnzKEvidence the response is based on: memories, mental models, and directives.z*Memory facts used to generate the responserr   memoriesz$Mental models used during reflectionmental_modelsz$Directives applied during reflection
directivesN)rM   rN   rO   rP   r1   r,   rj  rV  rR   rk  r]  rl  rZ  r+   r2   r   ri  ri  E  s         UU"2"24Eq"r"r"rHd;rrr.>.>tQw.x.x.xM4*+xxx)9)9$Lr)s)s)sJ%&sssssr2   ri  c                   t    e Zd ZU dZ eed          Zee         ed<    eed          Z	ee
         ed<   dS )ReflectTracez8Execution trace of LLM and tool calls during reflection.z!Tool calls made during reflectionrr   r6  z LLM calls made during reflection	llm_callsN)rM   rN   rO   rP   r1   r,   r6  r_  rR   ro  rf  r+   r2   r   rn  rn  M  sd         BB(8(8Kn(o(o(oJ_%ooo&6&6tIk&l&l&lItN#lllllr2   rn  c                   Z   e Zd ZU dZ edddddddd	d
ddgidddgddddddddiddgdddgddddd gd!d"i#          Z ed$%          Zee	d&<    ed'd()          Z
ed'z  e	d*<    ed'd+)          Zed'z  e	d,<    ed'd-)          Zed'z  e	d.<    ed'd/)          Zed'z  e	d0<   d'S )1ReflectResponsez"Response model for think endpoint.rb   z## AI Overview

Based on my understanding, AI is a **transformative technology**:

- Used extensively in healthcare
- Discussed in recent conversations
- Continues to evolve rapidlyrj  123rW  rd   )r   r   r   456z%I discussed AI applications last weekre   zAI is transformativezUsed in healthcarezDiscussed recentlyr=  i  rH   i  r  recallri   AIr   )r`  ra  rc  agent_1i  rg  rc  zobs-1zAI Technologyconcept
structural)r   r[  r   subtype)r6  ro  r   r   based_onstructured_outputr&  rl   rq   z`The reflect response as well-formatted markdown (headers, lists, bold/italic, code blocks, etc.)rr   r   NzOEvidence used to generate the response. Only present when include.facts is set.rI   r|  zStructured output parsed according to the request's response_schema. Only present when response_schema was provided in the request.r}  z4Token usage metrics for LLM calls during reflection.r&  zSExecution trace of tool and LLM calls. Only present when include.tool_calls is set.rl   )rM   rN   rO   rP   r"   r   r#   r   r   rR   r|  ri  r}  r   r&  r<   rl   rn  r+   r2   r   rq  rq  T  s        ,,: V$.HRYZZ$.U_kll!  6#79M"N& & +/VZ[[,4_b#c#c"d,5d"K"K!L #*$3$-'3	 %  
  L> v  D#    ',ee' ' 'Hnt#    &+U Z& & &td{     %uJ     E:    "'i" " "E<$     r2   rq  c                       e Zd ZU dZ edddddi          Z eddd	          Zee	d
<    eddd	          Z
ee	d<    eddd	          Zee	d<   dS )DispositionTraitszJDisposition traits that influence how memories are formed and interpreted.rb      
skepticism
literalismempathyrq   r   r   z3How skeptical vs trusting (1=trusting, 5=skeptical)gelerJ   r  z>How literally to interpret information (1=flexible, 5=literal)r  zAHow much to consider emotional context (1=detached, 5=empathetic)r  N)rM   rN   rO   rP   r"   r   r#   r  rQ   rR   r  r  r+   r2   r   r  r    s         TT:1\]jk<l<l0mnnnLeqQ4ijjjJjjjeqQ4tuuuJuuu5A!1tuuuGSuuuuur2   r  c            	           e Zd ZU dZ edddddddddi	          Zeed
<   eed<   eed<    e	d          Z
eed<    e	dd          Zedz  ed<   dS )BankProfileResponsez Response model for bank profile.rb   r  r   r  r  zMI am a software engineer helping my team stay organized and ship quality code)r$  r[  dispositionmissionrq   r$  r[  r  zHThe agent's mission - who they are and what they're trying to accomplishrr   r  NzDeprecated: use mission insteadrI   
background)rM   rN   rO   rP   r"   r   r   rR   r  r#   r  r  r+   r2   r   r  r    s         **:$./qQOOj	 
	 	 	L LLL
III""""5%opppGSppp"U4=^___Jd
_____r2   r  c                       e Zd ZU dZeed<   dS )UpdateDispositionRequestz.Request model for updating disposition traits.r  N)rM   rN   rO   rP   r  rR   r+   r2   r   r  r    s$         88""""""r2   r  c                   V    e Zd ZU dZ edddii          Z ed          Zee	d<   dS )	SetMissionRequestz7Request model for setting/updating the agent's mission.rb   r   z4I am a PM helping my engineering team stay organizedrq   zFThe mission content - who you are and what you're trying to accomplishrr   N)
rM   rN   rO   rP   r"   r   r#   r   r   rR   r+   r2   r   r  r    s\         AA:$y2h&ij  L 5%mnnnGSnnnnnr2   r  c                   >    e Zd ZU dZ edddii          Zeed<   dS )MissionResponsez"Response model for mission update.rb   r  zKI am a PM helping my engineering team stay organized and ship quality code.rq   NrM   rN   rO   rP   r"   r   r   rR   r+   r2   r   r  r    sJ         ,,:h
  L LLLLLr2   r  c                   |    e Zd ZU dZ eddddi          Z ed          Zee	d	<    edd
          Z
ee	d<   dS )AddBackgroundRequestzcRequest model for adding/merging background information. Deprecated: use SetMissionRequest instead.rb   zI was born in TexasT)r   update_dispositionrq   z*New background information to add or mergerr   r   z@Deprecated - disposition is no longer auto-inferred from missionrI   r  N)rM   rN   rO   rP   r"   r   r#   r   r   rR   r  r   r+   r2   r   r  r    s         mm:$2G_c&d&de  L 5%QRRRGSRRR$u"d          r2   r  c                   |    e Zd ZU dZ edddii          Zeed<    edd          Z	edz  ed	<   dZ
edz  ed
<   dS )BackgroundResponsezNResponse model for background update. Deprecated: use MissionResponse instead.rb   r  zJI was born in Texas. I am a software engineer with 10 years of experience.rq   NzDeprecated: same as missionrI   r  r  )rM   rN   rO   rP   r"   r   r   rR   r#   r  r  r  r+   r2   r   r  r    s         XX:g
  L LLL"U4=Z[[[Jd
[[[,0K"T)00000r2   r  c                       e Zd ZU dZeed<   dZedz  ed<   eed<   dZedz  ed<   dZ	edz  ed<   dZ
edz  ed<   d	Zeed
<   dZedz  ed<   dS )BankListItemz.Bank list item with profile summary and stats.r$  Nr[  r  r  
created_at
updated_atr   
fact_countlast_document_at)rM   rN   rO   rP   r   rR   r[  r  r  r  r  r  rQ   r  r+   r2   r   r  r    s         88LLLD#*""""GS4Z!Jd
!!!!Jd
!!!J#'cDj'''''r2   r  c                   f    e Zd ZU dZ edddddddddd	d
dd
dgii          Zee         ed<   dS )BankListResponsez%Response model for listing all banks.rb   banksr  r   r  r  z:I am a software engineer helping my team ship quality coder   z2024-01-16T14:20:00Z   )r$  r[  r  r  r  r  r  r  rq   N)	rM   rN   rO   rP   r"   r   r,   r  rR   r+   r2   r   r  r    s         //:#, '67qUV'W'W#_&<&<&),B	 	
  L& r2   r  c                      e Zd ZU dZ eddddi          Z edd	          Zedz  e	d
<    edd	          Z
edz  e	d<    edddd          Zedz  e	d<    edddd          Zedz  e	d<    edddd          Zedz  e	d<    edd	          Zedz  e	d<    edd	          Zedz  e	d<    edd	          Zedz  e	d<    edd	          Zedz  e	d<    edd	          Zedz  e	d<    edd	          Zedz  e	d<    edd	          Zedz  e	d<    edd 	          Zedz  e	d!<    edd"	          Zedz  e	d#<   d$eeef         fd%ZdS )&CreateBankRequestz+Request model for creating/updating a bank.rb   zZAlways include technical decisions and architectural trade-offs. Ignore meeting logistics.z_Observations are stable facts about people and projects. Always include preferences and skills.)retain_missionobservations_missionrq   Nz.Deprecated: display label only, not advertisedrI   r[  z*Deprecated: use update_bank_config insteadr  r   r   r*   r  r  rJ   disposition_skepticismdisposition_literalismdisposition_empathyz?Deprecated: use update_bank_config with reflect_mission insteadr  r  zXMission/context for Reflect operations. Guides how Reflect interprets and uses memories.reflect_missionzYSteers what gets extracted during retain(). Injected alongside built-in extraction rules.r  zBFact extraction mode: 'concise' (default), 'verbose', or 'custom'.retain_extraction_modezNCustom extraction prompt. Only active when retain_extraction_mode is 'custom'.retain_custom_instructionsz8Maximum token size for each content chunk during retain.retain_chunk_sizez:Toggle automatic observation consolidation after retain().enable_observationszaControls what gets synthesised into observations. Replaces built-in consolidation rules entirely.r  r   c                 j   i }| j         p| j        p| j        }|||d<   | j        | j        |d<   n| j        | j        j        |d<   | j        | j        |d<   n| j        | j        j        |d<   | j        | j        |d<   n| j        | j        j	        |d<   dD ]}t          | |          }||||<   |S )zReturn only the config fields that were explicitly set.

        reflect_mission takes precedence over deprecated mission/background aliases.
        Individual disposition_* fields take priority over the deprecated disposition dict.
        Nr  r  r  r  )r  r  r  r  r  r  )r  r  r  r  r  r  r  r  r  r  getattr)r   updatesresolved_reflect_mission
field_namevalues        r   get_config_updatesz$CreateBankRequest.get_config_updatesP  s    #%#'#7#Z4<#Z4? #/)AG%&&2040KG,--)040@0KG,-&2040KG,--)040@0KG,-#/-1-EG)**)-1-=-EG)*
 
	, 
	,J D*--E &+
#r2   )rM   rN   rO   rP   r"   r   r#   r[  r   rR   r  r  r  rQ   r  r  r  r  r  r  r  r  r  r  r   r  r   r   r  r+   r2   r   r  r    sA        55:"~ )J 
  L uT7ghhhD#*hhh,1E"N- - -K"T)    */q.Z* * *C$J    */q.Z* * *C$J    ',eq.Z' ' 't     %"c  GS4Z    #U"c  Jd
   
 #(%n# # #OS4Z    "'o" " "NC$J    */X* * *C$J    .3Ud. . .d
    %*EN% % %sTz    (-uP( ( (    (-uw( ( (#*   
#DcN # # # # # #r2   r  c                   n    e Zd ZU dZ eddddddii          Z ed	
          Zee	e
f         ed<   dS )BankConfigUpdatez.Request model for updating bank configuration.rb   r  zclaude-sonnet-4-5verbosez#Extract technical details carefully)	llm_modelr  r  rq   zConfiguration overrides. Keys can be in Python field format (llm_provider) or environment variable format (HINDSIGHT_API_LLM_PROVIDER). Only hierarchical fields can be overridden per-bank.rr   N)rM   rN   rO   rP   r"   r   r#   r  r   r   r   rR   r+   r2   r   r  r  v  s         88:!4.72W 

 
 
L $e?  GT#s(^     r2   r  c                       e Zd ZU dZ edddddddddd	i
          Z ed          Zee	d<    ed          Z
eeef         e	d<    ed          Zeeef         e	d<   dS )BankConfigResponsez&Response model for bank configuration.rb   zmy-bankopenaizgpt-4r  )llm_providerr  r  )r  r  r$  config	overridesrq   zBank identifierrr   r$  zYFully resolved configuration with all hierarchical overrides applied (Python field names)r  z?Bank-specific configuration overrides only (Python field names)r  N)rM   rN   rO   rP   r"   r   r#   r$  r   rR   r  r   r   r  r+   r2   r   r  r    s         00:$$,!(.7  ").7  
  L" 5%6777GS777"Uo  FDcN    !&2s t t tItCH~tttttr2   r  c                       e Zd ZU dZ edddddddddgddd	d
dgddddddgdddi          Zeeee	f                  e
d<   eeee	f                  e
d<   eeee	f                  e
d<   ee
d<   ee
d<   dS )GraphDataResponsez'Response model for graph data endpoint.rb   1r  rd   )r   r   r   2zBob went hikingsemanticg?)fromtor   r   zabc12345...z	Work infoz2024-01-15 10:30%Alice (PERSON), Google (ORGANIZATION))r   r   r   dater]   rx   r   )r   r   
table_rowstotal_unitsr   rq   r   r   r  r  r   Nr   r+   r2   r   r  r    s         11:)@'RR):GLL $'c:QTUUV , 7#. 2$K   !! 
  L. S#XS#XT#s(^$$$$JJJJJr2   r  c            
           e Zd ZU dZ edddddddd	gd
dddi          Zeeee	f                  e
d<   ee
d<   ee
d<   ee
d<   dS )ListMemoryUnitsResponsez.Response model for list memory units endpoint.rb   r-  r   zWork conversationr   rd   r  )r   r   r   r  r   r]   r   r   r   r   rq   r   r   r   r   Nr   r+   r2   r   r  r    s         88: E F#6 6 '$K 	  
  L( S#XJJJJJJKKKKKr2   r  c                       e Zd ZU dZ eddddddddd	d
gdgddddi          Zeeee	f                  e
d<   ee
d<   ee
d<   ee
d<   dS )ListDocumentsResponsez+Response model for list documents endpoint.rb   	session_1r  abc123r   i,  r   rg   session_123)r   r$  content_hashr  r  text_lengthmemory_unit_countro   2   r   r   r   rq   r   r   r   r   Nr   r+   r2   r   r  r    s         55: *#,(0&<&<'+-/!)= 9	 	  
  L, S#XJJJJJJKKKKKr2   r  c                   X    e Zd ZU dZ ed          Zeed<    ed          Ze	ed<   dS )TagItemzSingle tag with usage count.zThe tag valuerr   tagz Number of memories with this tagcountN)
rM   rN   rO   rP   r#   r  r   rR   r  rQ   r+   r2   r   r  r    sS         &&u111C111#EFFFE3FFFFFr2   r  c                       e Zd ZU dZ eddddddddd	dgd
dddi          Zee         ed<   e	ed<   e	ed<   e	ed<   dS )ListTagsResponsez&Response model for list tags endpoint.rb   z
user:alice*   )r  r  zuser:bobr   zsession:abc123r      r   r   r   rq   r   r   r   r   N)
rM   rN   rO   rP   r"   r   r,   r  rR   rQ   r+   r2   r   r  r    s         00:(266&44,q99
 	 	
  L =JJJJJJKKKKKr2   r  c                      e Zd ZU dZ eddddddddd	d
gddddddd
i          Zeed<   eed<   eed<   edz  ed<   eed<   eed<   eed<    e	dd          Z
eeef         dz  ed<    eed          Zee         ed <    e	dd!          Zeeef         dz  ed"<    e	dd#          Zeeef         dz  ed$<   dS )%DocumentResponsez)Response model for get document endpoint.rb   r  r  zFull document text here...r  r   r   rg   r  r   z#generalr   zTeam meeting notesz
2024-01-15)r   
event_date)
r   r$  original_textr  r  r  r  ro   document_metadataretain_paramsrq   r   r$  r  Nr  r  r  r  z;Memory count per fact type (world, experience, observation)rI   nodes_by_fact_typez"Tags associated with this documentrr   ro   zDocument metadatar  zParameters used during retainr  )rM   rN   rO   rP   r"   r   r   rR   rQ   r#   r  r   r1   r,   ro   r  r   r  r+   r2   r   r  r  #  s        33:!$!= (44%'!=107J%O%O-AQ]!^!^ 
  L" 	GGGLLL*OOOOOO05"_1 1 1S#X-    '&t9]^^^D$s)^^^/4uTOb/c/c/ctCH~,ccc+05Kj+k+k+kM4S>D(kkkkkr2   r  c                   n    e Zd ZU dZ eddddgii          Z edd	          Zee	         dz  e
d<   dS )
UpdateDocumentRequestz7Request model for updating a document's mutable fields.rb   ro   zteam-azteam-brq   NzgNew tags for the document and its memory units. Triggers observation invalidation and re-consolidation.rI   )rM   rN   rO   rP   r"   r   r#   ro   r,   r   rR   r+   r2   r   r  r  F  s         AA:8,
  L #UB  D$s)d
     r2   r  c                   "    e Zd ZU dZdZeed<   dS )UpdateDocumentResponsez,Response model for update document endpoint.Tr#  N)rM   rN   rO   rP   r#  r   rR   r+   r2   r   r  r  X  s(         66GTr2   r  c                   b    e Zd ZU dZ eddddddi          Zeed	<   eed
<   eed<   e	ed<   dS )DeleteDocumentResponsez,Response model for delete document endpoint.rb   TzGDocument 'session_1' and 5 associated memory units deleted successfullyr  r   r#  messager   memory_units_deletedrq   r#  r  r   r  N)
rM   rN   rO   rP   r"   r   r   rR   r   rQ   r+   r2   r   r  r  ^  sx         66:d*()	 
	 	 	L MMMLLLr2   r  c            
       z    e Zd ZU dZ edddddddd	i
          Zeed<   eed<   eed<   eed<   eed<   eed<   dS )ChunkResponsez&Response model for get chunk endpoint.rb   user123_session_1_0r  r  r   z*This is the first chunk of the document...r   )r   r   r$  r   
chunk_textr  rq   r   r   r$  r   r  r  N)	rM   rN   rO   rP   r"   r   r   rR   rQ   r+   r2   r   r  r  r  s         00:1*$ J4 	
  L MMMLLLOOOOOOOOr2   r  c                   H    e Zd ZU dZee         ed<   eed<   eed<   eed<   dS )ListChunksResponsez0Response model for listing chunks of a document.r   r   r   r   N)rM   rN   rO   rP   r,   r  rR   rQ   r+   r2   r   r  r    sB         ::JJJJJJKKKKKr2   r  c                   2    e Zd ZU dZeed<   eed<   eed<   dS )ReprocessDocumentResponsez/Response model for reprocess document endpoint.r#  r)  r%  N)rM   rN   rO   rP   r   rR   r   rQ   r+   r2   r   r  r    s9         99MMMr2   r  c                   j    e Zd ZU dZ edddddi          Zeed<   d	Ze	d	z  ed
<   d	Z
ed	z  ed<   d	S )DeleteResponsez%Response model for delete operations.rb   TzDeleted successfully
   r#  r  deleted_countrq   r#  Nr  r  )rM   rN   rO   rP   r"   r   r   rR   r  r   r  rQ   r+   r2   r   r  r    su         //:$$CYln&o&op  L MMMGS4Z $M3:$$$$$r2   r  c                   >    e Zd ZU dZ edddii          Zeed<   dS )ClearMemoryObservationsResponsez?Response model for clearing observations for a specific memory.rb   r  r  rq   NrM   rN   rO   rP   r"   r   rQ   rR   r+   r2   r   r  r    s@         II:_a<P0QRRRLr2   r  c                   >    e Zd ZU dZ edddii          Zeed<   dS )RecoverConsolidationResponsez3Response model for recovering failed consolidation.rb   retried_countr  rq   Nr  r+   r2   r   r  r    s@         ==:_b<Q0RSSSLr2   r  c                      e Zd ZU dZ edddddddd	d
dddddddd
dddddidddddddi          Zeed<   eed<   eed<   eed<   e	eef         ed<   e	eef         ed<   e	eef         ed<   e	ee	eef         f         ed<   eed<   eed <    e
e	d!"          Ze	eef         ed#<    e
d$d%&          Zed$z  ed'<    e
dd(&          Zeed)<    e
dd*&          Zeed+<    e
dd,&          Zeed-<   d$S ).BankStatsResponsez,Response model for bank statistics endpoint.rb   r  r   i,  r  r         )fact
preferencerF  r  )temporalr  entity   <   (   r  rx   r   r   -   )r$  total_nodestotal_linkstotal_documentsr  links_by_link_typelinks_by_fact_typelinks_breakdownpending_operationsfailed_operationslast_consolidated_atpending_consolidationfailed_consolidationtotal_observationsrq   r$  r  r  r  r  r  r  r  r  r  zWAsync operations grouped by status (pending, processing, completed, failed, cancelled).rC  operations_by_statusNz(When consolidation last ran (ISO format)rI   r  z6Number of memories not yet processed into observationsr  zNumber of source memories (world/experience) whose consolidation permanently failed and can be retried via the consolidation recovery endpoint.r  zTotal number of observationsr  )rM   rN   rO   rP   r"   r   r   rR   rQ   r   r#   r  r  r  r  r  r+   r2   r   r  r    s        66:$""#%/2"UW&X&X36CSU&V&V/2"UW&X&X$*"XZ,[,[#\&'%&(>)*()&( 
  L* LLLS#X&&&S#X&&&S#X&&&#tCH~-....+05m, , ,$sCx.   
 (-uTGq'r'r'r#*rrr!&q>v!w!w!w3www % f! ! !#    $eA;YZZZZZZZZr2   r  c                       e Zd ZU dZ ed          Zeed<    edd          Ze	ed<    edd	          Z
e	ed
<    edd          Ze	ed<   dS )MemoryTimeseriesBucketz/One bucket in the memory ingestion time-series.z)Bucket start timestamp in ISO-8601 (UTC).rr   timer   z,World-fact memories ingested in this bucket.rI   rd   z,Experience memories ingested in this bucket.re   z%Observations recorded in this bucket.rF  N)rM   rN   rO   rP   r#   r  r   rR   rd   rQ   re   rF  r+   r2   r   r  r    s         99"MNNND#NNNq.\]]]E3]]]eA3abbbJbbbuQ4[\\\K\\\\\r2   r  c                       e Zd ZU dZeed<    ed          Zeed<    ed          Zeed<    edd	
          Z	eed<    ee
d          Ze
e         ed<   dS )MemoriesTimeseriesResponsez?Time-series of memory ingestion bucketed by time and fact type.r$  z"One of: 1h, 12h, 1d, 7d, 30d, 90d.rr   periodz&Bucket granularity: minute, hour, day.truncr  zTimestamp column used to assign each row to a bucket. `created_at` shows ingest time; `mentioned_at` / `occurred_start` show event time (falls back to `created_at` per row when null).rI   
time_fieldzIPer-bucket counts, always returned fully padded for the requested period.rC  bucketsN)rM   rN   rO   rP   r   rR   r#   r!  r"  r#  r,   r$  r  r+   r2   r   r   r     s         IILLL%$HIIIFCIII#KLLLE3LLLeN  J    -2E_- - -GT()     r2   r   c                       e Zd ZU dZeed<   eed<   eed<   eed<   dZeed<   dZe	ed	<    e
e          Zee         ed
<   dZedz  ed<   dZedz  ed<   dS )DirectiveResponsezResponse model for a directive.r   r$  r[  r   r   priorityT	is_activero   Nr  r  )rM   rN   rO   rP   r   rR   r'  rQ   r(  r   r1   r,   ro   r  r  r+   r2   r   r&  r&    s         ))GGGLLL
IIILLLHcIt&&t,,D$s),,,!Jd
!!!!Jd
!!!!!r2   r&  c                   *    e Zd ZU dZee         ed<   dS )DirectiveListResponsez&Response model for listing directives.r   N)rM   rN   rO   rP   r,   r&  rR   r+   r2   r   r*  r*    s*         00!""""""r2   r*  c                       e Zd ZU dZ ed          Zeed<    ed          Zeed<    edd	          Z	e
ed
<    edd	          Zeed<    eed          Zee         ed<   dS )CreateDirectiveRequestz'Request model for creating a directive.z%Human-readable name for the directiverr   r[  )The directive text to inject into promptsr   r   -Higher priority directives are injected firstrI   r'  T Whether this directive is activer(  Tags for filteringro   NrM   rN   rO   rP   r#   r[  r   rR   r   r'  rQ   r(  r   r1   r,   ro   r+   r2   r   r,  r,     s         11"IJJJD#JJJ5%PQQQGSQQQE!1`aaaHcaaaeD6XYYYItYYY&&t9MNNND$s)NNNNNr2   r,  c                       e Zd ZU dZ edd          Zedz  ed<    edd          Zedz  ed<    edd          Z	e
dz  ed	<    edd
          Zedz  ed<    edd          Zee         dz  ed<   dS )UpdateDirectiveRequestz'Request model for updating a directive.NzNew namerI   r[  zNew contentr   zNew priorityr'  zNew active statusr(  zNew tagsro   )rM   rN   rO   rP   r#   r[  r   rR   r   r'  rQ   r(  r   ro   r,   r+   r2   r   r3  r3  *  s         11uTzBBBD#*BBB%-HHHGS4ZHHH 5>JJJHcDjJJJ"U4=PQQQItd{QQQ"U4ZHHHD$s)d
HHHHHr2   r3  c                   H   e Zd ZU dZ edd          Zed         ed<    edd          Ze	ed	<    ed
d          Z
eed                  d
z  ed<    edd          Ze	ed<    ed
d          Zee         d
z  ed<    ed
d          Zed
z  ed<    ed
d          Zee         d
z  ed<    ed
d          Ze	d
z  ed<    ed
d          Zed
z  ed<    ed
d          Zed
z  ed<    ed          edee         d
z  dee         d
z  fd                        Zd
S )MentalModelTriggerz$Trigger settings for a mental model.fulla  Refresh mode. 'full' (default) regenerates the mental model content from scratch on each refresh. 'delta' performs surgical edits against the existing content: unchanged sections are preserved byte-for-byte, stale content is removed, new content is added. If the mental model has no existing content, or if the source_query has changed since the last refresh, delta mode falls back to a full regeneration automatically.rI   )r6  deltar   FzTIf true, refresh this mental model after observations consolidation (real-time mode)refresh_after_consolidationNrD  rE  rG  rH  rI  rJ  rK  a  Override how the model's tags filter memories during refresh. If not set, defaults to 'all_strict' when the model has tags (security isolation) or 'any' when the model has no tags. Set to 'any' to include untagged memories alongside tagged ones during refresh.rp   a  Compound boolean tag expressions to use during refresh instead of the model's own tags. When set, these tag groups are passed to reflect and the model's flat tags are NOT used for filtering. Supports nested and/or/not expressions for complex tag-based scoping.ru   zOverride whether the internal recall used during refresh returns raw chunk text. None means use the bank/global config default (recall_include_chunks).include_chunkszOverride the token budget for facts returned by the internal recall during refresh. None means use the bank/global config default (recall_max_tokens).recall_max_tokenszOverride the token budget for raw chunks returned by the internal recall during refresh. None means use the bank/global config default (recall_chunks_max_tokens).recall_chunks_max_tokensrv   r   c                 N    |"t          |          dk    rt          d          |S rM  rN  rP  s     r   validate_fact_typesz&MentalModelTrigger.validate_fact_types}  rR  r2   )rM   rN   rO   rP   r#   r   r   rR   r8  r   rG  r,   rI  rK  r   rp   r>   ru   r=   r9  r:  rQ   r;  r$   r   r=  r+   r2   r   r5  r5  9  s        ..%*U*	& 	& 	&D'/
" 	 	 	 ).j) ) )    NSU CN N NJWABCdJ    #(%p# # #4    27Q2 2 2d3i$.    $)5^$ $ $J	D     ).T) ) )JX%    #(%U# # #ND4K    %*EQ% % %sTz    ,15X, , ,cDj    _\""DI$4 cT9I    [ #"  r2   r5  c                   h   e Zd ZU dZeed<   eed<   eed<   dZedz  ed<    edd          Zedz  ed	<    e	e
          Ze
e         ed
<    ed          Zedz  ed<    ed          Zedz  ed<   dZedz  ed<   dZedz  ed<    edd          Zedz  ed<    edd          Zedz  ed<   dS )MentalModelResponsez<Response model for a mental model (stored reflect response).r   r$  r[  Nsource_queryzZThe mental model content as well-formatted markdown (auto-generated from reflect endpoint)rI   r   ro   r*   rK   triggerlast_refreshed_atr  zKFull reflect API response payload including based_on facts and observationsreflect_responsezTrue when new memories matching this mental model's tag/fact_type scope have been ingested since last_refreshed_at, or consolidation has pending items. Only populated when detail=full.is_stale)rM   rN   rO   rP   r   rR   r@  r#   r   r1   r,   ro   rK   rQ   rB  r5  rC  r  rD  r   rE  r   r+   r2   r   r?  r?    sq        FFGGGLLL
III#L#*###%p  GS4Z    '&t,,D$s),,,"U4000Jd
000).t)<)<)<G$&<<<$(sTz(((!Jd
!!!$)Ea% % %dTk    "E   HdTk     r2   r?  c                   *    e Zd ZU dZee         ed<   dS )MentalModelListResponsez)Response model for listing mental models.r   N)rM   rN   rO   rP   r,   r?  rR   r+   r2   r   rG  rG    s*         33#$$$$$$r2   rG  c            
       .   e Zd ZU dZ edddddgddd	id
i          Z edd          Zedz  e	d<    ed          Z
ee	d<    ed          Zee	d<    eed          Zee         e	d<    edddd          Zee	d<    eed          Zee	d<   dS )CreateMentalModelRequestz*Request model for creating a mental model.rb   zteam-communicationzTeam Communication Preferences(How does the team prefer to communicate?team   r8  Fr   r[  r@  ro   rK   rB  rq   NzMOptional custom ID for the mental model (alphanumeric lowercase with hyphens)rr   r   (Human-readable name for the mental modelr[  $The query to run to generate contentr@  Tags for scoped visibilityro      rU   $Maximum tokens for generated contentr  rK   Trigger settingsrB  )rM   rN   rO   rP   r"   r   r#   r   r   rR   r[  r@  r1   r,   ro   rK   rQ   r5  rB  r+   r2   r   rI  rI    s6        44:*8 J"95A 	
  L Ui  Bd
    "LMMMD#MMM*PQQQL#QQQ&&t9UVVVD$s)VVVeDSTGmnnnJnnn"2"23ESe"f"f"fGfffffr2   rI  c                   `    e Zd ZU dZ edd          Zedz  ed<    ed          Zeed<   dS )CreateMentalModelResponsez)Response model for mental model creation.NzID of the created mental modelrr   mental_model_idz&Operation ID to track refresh progressr)  )	rM   rN   rO   rP   r#   rV  r   rR   r)  r+   r2   r   rU  rU    sZ         33"'%:Z"["["[OS4Z[[[*RSSSL#SSSSSr2   rU  c            	       &   e Zd ZU dZ eddddddgdd	id
i          Z edd          Zedz  e	d<    edd          Z
edz  e	d<    edddd          Zedz  e	d<    edd          Zee         dz  e	d<    edd          Zedz  e	d<   dS )UpdateMentalModelRequestz*Request model for updating a mental model.rb   z&Updated Team Communication PreferencesrJ  rX   rK  communicationr8  T)r[  r@  rK   ro   rB  rq   NzNew name for the mental modelrI   r[  z%New source query for the mental modelr@  rQ  rU   rR  r  rK   rP  ro   rS  rB  )rM   rN   rO   rP   r"   r   r#   r[  r   rR   r@  rK   rQ   ro   r,   rB  r5  r+   r2   r   rX  rX    s        44:@ J"194@ 

 
 
L uT7VWWWD#*WWW$uT?fgggL#*ggg"U4CDNtuuuJd
uuu"U4=YZZZD$s)d
ZZZ).tI[)\)\)\G$&\\\\\r2   rX  r  c                   8   e Zd ZU dZ ed          Zeed<    ed          Zeed<    ed          Z	eed<    e
ed	          Zee         ed
<    edddd          Zeed<    e
ed          Zeed<    ed          ededefd                        ZdS )BankTemplateMentalModelz:A mental model definition within a bank template manifest.zDUnique ID for the mental model (alphanumeric lowercase with hyphens)rr   r   rN  r[  rO  r@  rP  ro   rL  rQ  rU   rR  r  rK   rS  rB  rv   r   c                 V    t          j        d|          st          d| d          |S )Nz^[a-z0-9][a-z0-9-]*$zMental model id 'zO' must be alphanumeric lowercase with hyphens, starting with a letter or digit.)rematchr{   rP  s     r   validate_idz#BankTemplateMentalModel.validate_id  s@     x/33 	vAvvv   r2   N)rM   rN   rO   rP   r#   r   r   rR   r[  r@  r1   r,   ro   rK   rQ   r5  rB  r$   r   r_  r+   r2   r   r[  r[    s#        DDe fgggBggg"LMMMD#MMM*PQQQL#QQQ&&t9UVVVD$s)VVVeDSTGmnnnJnnn"2"23ESe"f"f"fGfff_TC C    [   r2   r[  c                   z   e Zd ZU dZ edd          Zedz  ed<    edd          Zedz  ed<    edd          Z	edz  ed	<    edd
          Z
edz  ed<    edd          Zedz  ed<    edd          Zedz  ed<    edd          Zedz  ed<    edddd          Zedz  ed<    edddd          Zedz  ed<    edddd          Zedz  ed<    edd          Zeeeef                  dz  ed<    edd          Zedz  ed<    edd          Zedz  ed <    edd!          Zedz  ed"<    edd#          Zedz  ed$<    edd%          Zee         dz  ed&<    edd'          Zedz  ed(<    edd)          Zedz  ed*<    edd+          Zedz  ed,<    edd-          Zedz  ed.<    edd/          Z edz  ed0<    edd1          Z!edz  ed2<    edd3          Z"edz  ed4<    edd5          Z#edz  ed6<    edd7          Z$edz  ed8<    edd9          Z%edz  ed:<    edd;          Z&e'dz  ed<<    edd=          Z(e'dz  ed><    edd?          Z)e'dz  ed@<    eddA          Z*edz  edB<    eddC          Z+edz  edD<   dEeeef         fdFZ,dS )GBankTemplateConfigzBank configuration fields within a template manifest.

    Only includes configurable (per-bank) fields. Credential fields
    (API keys, base URLs) are intentionally excluded for security.
    Nz&Mission/context for Reflect operationsrI   r  z(Steers what gets extracted during retainr  zAFact extraction mode: 'concise' (default), 'verbose', or 'custom'r  z-Custom extraction prompt (when mode='custom')r  z%Max token size for each content chunkr  z Toggle observation consolidationr  zControls what gets synthesisedr  r   r   zSkepticism trait (1-5)r  r  zLiteralism trait (1-5)r  zEmpathy trait (1-5)r  z'Controlled vocabulary for entity labelsentity_labelsz+Allow entities outside the label vocabularyentities_allow_free_formzDName of the default retain strategy (key into retain_strategies map)retain_default_strategyz7Map of retain strategy name to per-strategy config dictretain_strategiesz4Max chunks per streaming batch (0 disables batching)retain_chunk_batch_sizez3MCP tool allowlist for this bank (None = all tools)mcp_enabled_toolsz,LLM batch size for observation consolidationconsolidation_llm_batch_sizez2Max tokens of source facts per consolidation batch%consolidation_source_facts_max_tokensz*Max tokens of source facts per observation5consolidation_source_facts_max_tokens_per_observationz2Max observations to retain per consolidation scopemax_observations_per_scopez+Max tokens of source facts per reflect callreflect_source_facts_max_tokensz/Per-bank Gemini/VertexAI safety filter settingsllm_gemini_safety_settingsz5Recall budget mapping function: 'fixed' or 'adaptive'recall_budget_functionz7Fixed thinking_budget for budget=low (function='fixed')recall_budget_fixed_lowz7Fixed thinking_budget for budget=mid (function='fixed')recall_budget_fixed_midz8Fixed thinking_budget for budget=high (function='fixed')recall_budget_fixed_highz8Ratio of max_tokens for budget=low (function='adaptive')recall_budget_adaptive_lowz8Ratio of max_tokens for budget=mid (function='adaptive')recall_budget_adaptive_midz9Ratio of max_tokens for budget=high (function='adaptive')recall_budget_adaptive_highz0Floor for the adaptive function (after clamping)recall_budget_minz2Ceiling for the adaptive function (after clamping)recall_budget_maxr   c                 b    d |                                                                  D             S )z;Return only the fields that were explicitly set (non-None).c                     i | ]
\  }}|||S Nr+   .0krv   s      r   
<dictcomp>z9BankTemplateConfig.get_config_updates.<locals>.<dictcomp>Q  s    LLLAam1mmmr2   )
model_dumpr   r   s    r   r  z%BankTemplateConfig.get_config_updatesO  s,    LL!2!2!8!8!:!:LLLLr2   )-rM   rN   rO   rP   r#   r  r   rR   r  r  r  r  rQ   r  r   r  r  r  r  rb  r,   r   r   rc  rd  re  rf  rg  rh  ri  rj  rk  rl  rm  rn  ro  rp  rq  rr  floatrs  rt  ru  rv  r  r+   r2   r   ra  ra    s0          #(%Bj"k"k"kOS4Zkkk!&tAk!l!l!lNC$Jlll)."e* * *C$J    .3U"Q. . .d
    %*E$Dk$l$l$lsTzlll',uTGi'j'j'jjjj',uTGg'h'h'h#*hhh).taUm)n)n)nC$Jnnn).taUm)n)n)nC$Jnnn&+eDQ1Rg&h&h&hthhh16"K2 2 2M4S#X'$.    -2E"O- - -dTk    +0%"h+ + +S4Z    &+U"[& & &td{    +0%"X+ + +S4Z    +0%"W+ + +tCy4'    05u"P0 0 0 #*    9>"V9 9 9)3:    IN"NI I I93:    .3U"V. . .d
    38%"O3 3 3#S4Z    /4e"S/ / /t    */"Y* * *C$J    +0%"[+ + +S4Z    +0%"[+ + +S4Z    ,15"\, , ,cDj    05u"\0 0 0    05u"\0 0 0    16"]1 1 1    %*E$Dv$w$w$wsTzwww$)E"V% % %sTz   MDcN M M M M M Mr2   ra  c                       e Zd ZU dZ ed          Zeed<    ed          Zeed<    edd	          Z	e
ed
<    edd	          Zeed<    eed          Zee         ed<   dS )BankTemplateDirectivezA directive definition within a bank template manifest.

    Directives are matched by name on re-import: existing directives
    with the same name are updated, new ones are created.
    zFHuman-readable name for the directive (used as match key on re-import)rr   r[  r-  r   r   r.  rI   r'  Tr/  r(  r0  ro   Nr1  r+   r2   r   r  r  T  s           "jkkkD#kkk5%PQQQGSQQQE!1`aaaHcaaaeD6XYYYItYYY&&t9MNNND$s)NNNNNr2   r  c            
       $   e Zd ZU dZ edddddddd	d
dddidgddddgdi          Z ed          Zee	d<    edd          Z
edz  e	d<    edd          Zee         dz  e	d<    edd          Zee         dz  e	d<    ed          eded efd!                        Z ed          edee         dz  d ee         dz  fd"                        Z ed          edee         dz  d ee         dz  fd#                        ZdS )$BankTemplateManifestzA bank template manifest for import/export.

    Version field enables forward-compatible schema evolution: the API
    auto-upgrades older manifest versions to the current schema on import.
    rb   r  z?You are helping a support agent remember customer interactions.z4Extract customer issues, resolutions, and sentiment.r   T)r  r  r  r  zsentiment-overviewzCustomer Sentiment Overviewz$What is the overall sentiment trend?r8  )r   r[  r@  rB  zAlways be empatheticz.Always respond with empathy and understanding.r  )r[  r   r'  versionbankrk  rl  rq   z'Manifest schema version (currently '1')rr   r  Nz<Bank configuration to apply. Omit to leave config unchanged.rI   r  zKMental models to create or update (matched by id). Omit to leave unchanged.rk  zJDirectives to create or update (matched by name). Omit to leave unchanged.rl  rv   r   c                     	 t          |          }n!# t          $ r t          d| d          w xY w|dk     rt          d          |t          t                    k    rt          d| dt           d          |S )Nz'version must be a numeric string, got ''r   zversion must be >= 1z	version 'z2' is not supported by this server (max supported: z). Please upgrade Hindsight.)rQ   r{   BANK_TEMPLATE_CURRENT_VERSION)r|   rv   vers      r   validate_versionz%BankTemplateManifest.validate_version  s    	Ma&&CC 	M 	M 	MKqKKKLLL	M77344423333_A _ _#@_ _ _   s    0c                     ||S d |D             fdD             }|r,t          dt          t          |                               |S )Nc                     g | ]	}|j         
S r+   r   r{  ms     r   
<listcomp>zIBankTemplateManifest.validate_unique_mental_model_ids.<locals>.<listcomp>  s    qtr2   c                 F    g | ]}                     |          d k    |S r   r  )r{  rf   idss     r   r  zIBankTemplateManifest.validate_unique_mental_model_ids.<locals>.<listcomp>  s-    ???cCIIcNNQ,>,>c,>,>,>r2   zDuplicate mental model ids: r{   sortedset)r|   rv   
duplicatesr  s      @r    validate_unique_mental_model_idsz5BankTemplateManifest.validate_unique_mental_model_ids  sn     9HQ????S???
 	WUF3z??<S<SUUVVVr2   c                     ||S d |D             fdD             }|r,t          dt          t          |                               |S )Nc                     g | ]	}|j         
S r+   r[  r{  ds     r   r  zHBankTemplateManifest.validate_unique_directive_names.<locals>.<listcomp>  s    ###A###r2   c                 F    g | ]}                     |          d k    |S r  r  )r{  nnamess     r   r  zHBankTemplateManifest.validate_unique_directive_names.<locals>.<listcomp>  s-    ===A%++a..1*<*<a*<*<*<r2   zDuplicate directive names: r  )r|   rv   r  r  s      @r   validate_unique_directive_namesz4BankTemplateManifest.validate_unique_directive_names  sn     9H#####=======
 	VT6#j//;R;RTTUUUr2   )rM   rN   rO   rP   r"   r   r#   r  r   rR   r  ra  rk  r,   r[  rl  r  r$   r   r  r  r  r+   r2   r   r  r  b  sd          :'h&\+,+/	  3 =(N$A4#H	 " !7#S$& ! 
  L: 5%NOOOGSOOO&+e"`' ' 'D
t
#    ;@%"o; ; ;M4/047    6;U"n6 6 6J*+d2    _Y     [   __%%
'(4/
 
%	&	-
 
 
 [ &%
 _\""
%&-
 
#	$t	+
 
 
 [ #"
 
 
r2   r  c                   l   e Zd ZU dZ ed          Zeed<    ed          Ze	ed<    e
ed          Zee         ed<    e
ed	          Zee         ed
<    e
ed          Zee         ed<    e
ed          Zee         ed<    e
ed          Zee         ed<    edd          Ze	ed<   dS )BankTemplateImportResponsez5Response model for the bank template import endpoint.zBank that was imported intorr   r$  zWhether bank config was updatedconfig_appliedz"IDs of newly created mental modelsmental_models_createdzIDs of updated mental modelsmental_models_updatedz!Names of newly created directivesdirectives_createdzNames of updated directivesdirectives_updatedz9Operation IDs for mental model content generation (async)r*  Fz&True if this was a validation-only runrI   dry_runN)rM   rN   rO   rP   r#   r$  r   rR   r  r   r1   r,   r  r  r  r  r*  r  r+   r2   r   r  r    s@        ??5%BCCCGSCCC 5-NOOONDOOO'7'7Jn'o'o'o49ooo'7'7Jh'i'i'i49iii$4$4TGj$k$k$kS	kkk$4$4TGd$e$e$eS	eee//U     M49    E%5]^^^GT^^^^^r2   r  manifestc                    g }| j         ra| j         }|j        ,d}|j        |vr!|                    d| d|j         d           |j        r |j        dk    r|                    d           | j        r~t          | j                  D ]i\  }}|j                                        s|                    d| d	           |j                                        s|                    d| d
           j| j	        r~t          | j	                  D ]i\  }}|j                                        s|                    d| d	           |j
                                        s|                    d| d           j|S )zValidate a parsed manifest beyond Pydantic's structural checks.

    Returns a list of human-readable error strings (e.g. invalid
    extraction mode values, conflicting settings).
    N)conciser  customr^   z,bank.retain_extraction_mode: must be one of z, got 'r  r  zIbank.retain_custom_instructions: requires retain_extraction_mode='custom'zmental_models[z].name: must not be emptyz!].source_query: must not be emptyzdirectives[z].content: must not be empty)r  r  r   r  rk  	enumerater[  stripr@  rl  r   )r  errorsr  valid_modesimmr  s          r   validate_bank_templater    s    F} 	g}&2DK*+==u;uuW[Wruuu   * 	gt/Jh/V/VMMefff Ux566 	U 	UEAr7==?? MKqKKKLLL?((** USqSSSTTT Mh122 	M 	MDAq6<<>> JHAHHHIII9??$$ MKAKKKLLLMr2   r$  request_contextrE   c                 z  K   d}|j         r?|j                                         }|r$| j                            |||           d{V  d}g }g }g }|j        r|                     ||           d{V }	d |	D             }
|j        D ]}|j        |
v r|                     ||j        |j        |j	        |j
        |j        r|j        nd|j        r|j                                        nd|           d{V  |                     ||j        |           d{V }|                    |d                    |                    |j                   |                     ||j        |j	        d	|j        |j        r|j        nd|j
        |j        r|j                                        nd|
	  	         d{V }|                     ||d         |           d{V }|                    |d                    |                    |j                   g }g }|j        r|                     |d|           d{V }d |D             }|j        D ]}|j        |v rk|                     |||j                 d         |j        |j        |j        |j        r|j        nd|           d{V  |                    |j                   v|                     ||j        |j        |j        |j        |j        r|j        nd|           d{V  |                    |j                   t1          |||||||d          S )a*  Apply a validated BankTemplateManifest to an existing bank.

    Shared by the /import endpoint and the default-template-on-create hook
    driven by HINDSIGHT_API_DEFAULT_BANK_TEMPLATE. The bank MUST already
    exist; caller is responsible for validation (Pydantic + validate_bank_template).
    FNTr$  r  c                      i | ]}|d          |S r  r+   r  s     r   r}  z0apply_bank_template_manifest.<locals>.<dictcomp>  s    777!D'1777r2   r$  rV  r[  r@  rK   ro   rB  r  r$  rV  r  r)  Generating content...	r$  r[  r@  r   rV  ro   rK   rB  r  r   r$  active_onlyr  c                      i | ]}|d          |S r  r+   r  s     r   r}  z0apply_bank_template_manifest.<locals>.<dictcomp>7  s    FFFQAfIqFFFr2   )r$  directive_idr   r'  r(  ro   r  r$  r[  r   r'  r(  ro   r  )r$  r  r  r  r  r  r*  r  )r  r  _config_resolverupdate_bank_configrk  list_mental_modelsr   update_mental_modelr[  r@  rK   ro   rB  r~  !submit_async_refresh_mental_modelr   create_mental_modelrl  list_directivesupdate_directiver   r'  r(  create_directiver  )memoryr$  r  r  r  config_updatescreated_idsupdated_idsr*  existingexisting_by_idr  resultmental_modelr  r  existing_directivesexisting_by_name	directives                      r   apply_bank_template_manifestr    s      N} "!99;; 	")<<WnVefffffffff!NKK!M **227Tc2dddddddd77h777( %	* %	*Bu&&00#$&E!#!}$&G579zKBJ11333t$3 1 	 	 	 	 	 	 	 	 	  &GG#$&E$3  H          
 $$VN%;<<<""25))))%+%?%?#!#3$&E$&G5!}79zKBJ11333t$3 &@ 
& 
& 
  
  
  
  
  
   &GG#$0$6$3  H          
 $$VN%;<<<""25))))$&$& :$*$:$: %; %
 %
 
 
 
 
 
 
 GF2EFFF!, 	: 	:I~!111--#!1).!A$!G%-&/'1+4>Ct$3 .          #))).9999--#"%-&/'1+4>Ct$3 .          #))).9999%%))--#	 	 	 	r2   c                       e Zd ZU dZ eddddddddd	dd
	i          Zeed<   eed<   eed<   dZ	edz  ed<   eed<   eed<   edz  ed<    e
dd          Zedz  ed<    e
dd          Zedz  ed<   dS )OperationResponsez,Response model for a single async operation.rb   r-  retainr   Nr   pendingr   )	r   	task_typer%  r   r  statuserror_messageretry_countnext_retry_atrq   r   r  r%  r   r  r  r  >Number of times this operation has been retried after failure.rI   r  u>  When the worker will next attempt this operation. For a pending operation, a value in the future indicates the task is waiting rather than available for immediate pickup — for example, an extension may have raised DeferOperation to park the task until some backpressure window opens. Always null for completed tasks.r  )rM   rN   rO   rP   r"   r   r   rR   rQ   r   r#   r  r  r+   r2   r   r  r  ]  s        66:<% #4#!% !%
 

  L  	GGGNNN"Kt"""OOOKKK:#eT  Kt    !&O	! 	! 	!M3: 	 	 	 	 	r2   r  c                   Z    e Zd ZU dZ ed          Zeed<    edd          Ze	ed<   d	S )
ConsolidationResponsez2Response model for consolidation trigger endpoint.z'ID of the async consolidation operationrr   r)  Fz+True if an existing pending task was reusedrI   deduplicatedN)
rM   rN   rO   rP   r#   r)  r   rR   r  r   r+   r2   r   r  r    sV         <<*STTTL#TTTu:ghhhL$hhhhhr2   r  c                       e Zd ZU dZ edddddddd	d
ddgdi          Zeed<   eed<   eed<   eed<   e	e
         ed<   dS )OperationsListResponsez,Response model for list operations endpoint.rb   r  r   r  r   r-  r  r   r  N)r   r  r  r  r  r$  r   r   r   
operationsrq   r$  r   r   r   r  )rM   rN   rO   rP   r"   r   r   rR   rQ   r,   r  r+   r2   r   r  r    s         66:$ E%-&<"+)-  
  L( LLLJJJJJJKKK&''''''r2   r  c                   V    e Zd ZU dZ edddddi          Zeed<   eed	<   eed
<   dS )CancelOperationResponsez-Response model for cancel operation endpoint.rb   Tz8Operation 550e8400-e29b-41d4-a716-446655440000 cancelledr-  r#  r  r)  rq   r#  r  r)  N	rM   rN   rO   rP   r"   r   r   rR   r   r+   r2   r   r  r    si         77:U F 
  L MMMLLLr2   r  c                   V    e Zd ZU dZ edddddi          Zeed<   eed	<   eed
<   dS )RetryOperationResponsez,Response model for retry operation endpoint.rb   Tz?Operation 550e8400-e29b-41d4-a716-446655440000 queued for retryr-  r  rq   r#  r  r)  Nr  r+   r2   r   r  r    si         66:\ F 
  L MMMLLLr2   r  c                   d    e Zd ZU dZeed<   eed<   dZedz  ed<   dZedz  ed<   dZ	edz  ed<   dS )ChildOperationStatusz3Status of a child operation (for batch operations).r)  r  Nsub_batch_indexr%  r  )
rM   rN   rO   rP   r   rR   r  rQ   r%  r  r+   r2   r   r  r    si         ==KKK"&OS4Z&&&"Kt""" $M3:$$$$$r2   r  c                      e Zd ZU dZ eddddddddd	i
          Zeed<   ed         ed<   dZ	edz  ed<   dZ
edz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<    edd          Zedz  ed<    edd          Zedz  ed<    edd          Zeeef         dz  ed<    edd          Zee         dz  ed<    edd          Zeeef         dz  ed<   dS )OperationStatusResponsez5Response model for getting a single operation status.rb   r-  	completedrefresh_mental_modelsr   z2024-01-15T10:31:30ZN)r)  r  operation_typer  r  completed_atr  rq   r)  )r  
processingr  failed	cancelled	not_foundr  r  r  r  r  r  r  rI   r  zWhen the worker will next attempt this operation. For a pending operation, a value in the future indicates the task is parked (e.g. by an extension raising DeferOperation) rather than awaiting immediate pickup.r  z]Internal metadata for debugging. Structure may change without notice. Not for production use.result_metadataz5Child operations for batch operations (if applicable)child_operationszeRaw task payload (params the operation was submitted with). Only populated when include_payload=true.task_payload)rM   rN   rO   rP   r"   r   r   rR   r   r  r  r  r  r  r#   r  rQ   r  r  r   r   r  r,   r  r  r+   r2   r   r  r    s        ??: F%"944 6!% 

  L \]]]]!%NC$J%%%!Jd
!!!!Jd
!!!#L#*### $M3:$$$#eT  Kt    !& ! ! !M3:    .3Us. . .OT#s(^d*    ;@%"Y; ; ;d/047    +0%{+ + +L$sCx.4'     r2   r  c                   J    e Zd ZU dZ eddddi          Zeed<   eed<   d	S )
AsyncOperationSubmitResponsez1Response model for submitting an async operation.rb   r-  queuedr)  r  rq   r)  r  Nr  r+   r2   r   r  r  	  s[         ;;: F" 
  L KKKKKr2   r  c                       e Zd ZU dZ ed          Zeed<    ed          Zeed<    ed          Z	eed<    ed	          Z
eed
<    ed          Zeed<   dS )FeaturesInfoz8Feature flags indicating which capabilities are enabled.z5Whether observations (auto-consolidation) are enabledrr   r   z6Whether MCP (Model Context Protocol) server is enabledmcpz(Whether the background worker is enabledworkerz-Whether per-bank configuration API is enabledbank_config_apiz-Whether file upload/conversion API is enabledfile_upload_apiN)rM   rN   rO   rP   r#   r   r   rR   r  r  r  r	  r+   r2   r   r  r  	  s         BB+bcccL$ccc"Z[[[C[[[5%OPPPFDPPP!E.]^^^OT^^^!E.]^^^OT^^^^^r2   r  c            
           e Zd ZU dZ edddddddddi          Z ed	
          Zee	d<    ed
          Z
ee	d<   dS )VersionResponsez-Response model for the version/info endpoint.rb   z0.4.0FTr   r  r  r  r	  api_versionfeaturesrq   zAPI version stringrr   r  zEnabled feature flagsr  N)rM   rN   rO   rP   r"   r   r#   r  r   rR   r  r  r+   r2   r   r  r  &	  s         77:&$)"','+ 	 	
  L u)=>>>K>>>"U/FGGGHlGGGGGr2   r  )WebhookHttpConfigc                       e Zd ZU dZ ed          Zeed<    edd          Zedz  ed<    ed	gd
          Z	e
e         ed<    edd          Zeed<    eed          Zeed<   dS )CreateWebhookRequestz(Request model for registering a webhook.z)HTTP(S) endpoint URL to deliver events torr   urlNz%HMAC-SHA256 signing secret (optional)rI   secretzconsolidation.completedzNList of event types to deliver. Currently supported: 'consolidation.completed'event_typesTWhether this webhook is activeenabledz>HTTP delivery configuration (method, timeout, headers, params)rC  http_config)rM   rN   rO   rP   r#   r  r   rR   r  r  r,   r  r   r  r  r+   r2   r   r  r  D	  s         22u!LMMMCMMMt9`aaaFC$Jaaa"U*+d  Kc    E$4TUUUGTUUU%*U)T& & &K"     r2   r  c                       e Zd ZU dZeed<   edz  ed<   eed<    edd          Zedz  ed<   ee         ed	<   e	ed
<    ee
          Ze
ed<   dZedz  ed<   dZedz  ed<   dS )WebhookResponsezResponse model for a webhook.r   Nr$  r  z&Signing secret (redacted in responses)rI   r  r  r  )r'   r  r  r  )rM   rN   rO   rP   r   rR   r#   r  r,   r   r  r  r  r  r+   r2   r   r  r  T	  s         ''GGG4Z	HHHt9abbbFC$JbbbcMMM%*U;L%M%M%MK"MMM!Jd
!!!!Jd
!!!!!r2   r  c                       e Zd ZU dZ edd          Zedz  ed<    edd          Zedz  ed<    edd          Z	e
e         dz  ed	<    edd
          Zedz  ed<    edd          Zedz  ed<   dS )UpdateWebhookRequestzGRequest model for updating a webhook. Only provided fields are updated.NzHTTP(S) endpoint URLrI   r  zFHMAC-SHA256 signing secret. Omit to keep existing; send null to clear.r  zList of event typesr  r  r  zHTTP delivery configurationr  )rM   rN   rO   rP   r#   r  r   rR   r  r  r,   r  r   r  r  r+   r2   r   r  r  b	  s         QQeD6LMMMCtMMM"j  FC$J    %*E$DY$Z$Z$ZKcT!ZZZ 5;[\\\GTD[\\\,1E$Li,j,j,jK"T)jjjjjr2   r  c                   *    e Zd ZU dZee         ed<   dS )WebhookListResponsez$Response model for listing webhooks.r   N)rM   rN   rO   rP   r,   r  rR   r+   r2   r   r  r  n	  s)         ..      r2   r  c                      e Zd ZU dZeed<   edz  ed<   eed<   eed<   eed<   eed<   dZedz  ed	<   dZedz  ed
<   dZ	edz  ed<   dZ
edz  ed<   dZedz  ed<   dZedz  ed<   dZedz  ed<   ededd fd            ZdS )WebhookDeliveryResponsez-Response model for a webhook delivery record.r   N
webhook_idr  
event_typer  attemptsr  
last_errorlast_response_statuslast_response_bodylast_attempt_atr  r  rowr   c                    dd l }|d         }t          |t                    r|                    |          }nt          |t                    r|}ni }|                    d          }t          |t                    r|r|                    |          ni }nt          |t                    r|}ni } | t          |d                   |                    d          |                    dd          |                    dd          |d	         |d
         dz   |d         |d         |                    d          |                    d          |                    d          |d         |d                   S )Nr   r  r  r)  r!  r  r   r"  r  r  r   r  r  last_status_coder&  r'  r  r  )r   r!  r  r"  r  r#  r  r$  r%  r&  r'  r  r  )r   r   r   r   r   get)r|   r(  _jsonrawr  raw_metar  s          r   from_async_operation_rowz0WebhookDeliveryResponse.from_async_operation_row	  s   .!c3 	 ;;s++LLT"" 	LLL77,--h$$ 	!7?Gekk(333ROO$'' 	!&OO Os3~&''#''55  ++#''b99x='!+o.?+!0!4!45G!H!H.223GHH+//0ABB<(<(
 
 
 	
r2   )rM   rN   rO   rP   r   rR   rQ   r  r$  r%  r&  r'  r  r  r   r   r/  r+   r2   r   r   r   t	  s        77GGGd
	HHHOOOKKKMMM $M3:$$$!Jd
!!!'+#*+++%)d
)))"&OS4Z&&&!Jd
!!!!Jd
!!!!
4 !
4M !
 !
 !
 [!
 !
 !
r2   r   c                   >    e Zd ZU dZee         ed<   dZedz  ed<   dS )WebhookDeliveryListResponsez.Response model for listing webhook deliveries.r   Nnext_cursor)	rM   rN   rO   rP   r,   r   rR   r2  r   r+   r2   r   r1  r1  	  s>         88'(((("Kt"""""r2   r1  audit_logger_getterc                 x     ddl m  ddl m ddlm ddlm} dddt          d	t          d
z  f fd}|S )zCreate an audit decorator bound to an audit logger getter.

    Returns a decorator factory that can be used as @audited("action_name").
    r   )r   )r   )wrapsr   requestrequest_paramactionr8  Nc                       fd}|S )a=  Decorator that wraps an HTTP handler with audit logging.

        Args:
            action: The audit action name (e.g. "retain", "recall").
            request_param: Name of the kwarg holding the Pydantic request model
                           (None if handler has no request body). Also supports "body".
        c                 |                  fd            }dd l }|                               |_        |S )Nc                  .  K                }||                               s | i | d {V S |                    d          }	                    
j                  }d }rW|                              }|'t	          |d          r|                    d          }n|t          |t                    r|}t          d|||          }	  | i | d {V }t	          |d          r|                    d          |_	        nt          |t                    r||_	        |	                    
j                  |_
        |                    |           S # 	                    
j                  |_
        |                    |           w xY w)Nr$  r~  r   r   http)r9  	transportr$  
started_atr6  )
is_enabledr+  nowutchasattrr~  r   r   r   responseended_atlog_fire_and_forget)argsr.   alr$  r?  req_datareq_objentryr  _dt_tzr9  r3  funcr8  s            r   wrapperzG_make_audited_http.<locals>.audited.<locals>.decorator.<locals>.wrapper	  s     ((**:R]]6%:%::!%t!6v!6!66666666 **Y// WWSW--
  +$jj77G*ww/M/M*#*#5#56#5#B#B ,GT1J1J,#*"!$#)$  	2#'4#8#8#8888888Fv|44 0)/):):):)G)G#FD11 0)/!%(WWSW%5%5EN**51111 &)WWSW%5%5EN**51111s   AE 6Fr   )inspect	signature__signature__)	rN  rO  rP  rL  rM  r9  r3  r8  r5  s	   `  r   	decoratorz6_make_audited_http.<locals>.audited.<locals>.decorator	  so    U4[[!2 !2 !2 !2 !2 !2 !2 !2 !2 [!2H NNN$+$5$5d$;$;G!Nr2   r+   )r9  r8  rS  rL  rM  r3  r5  s   `` r   auditedz#_make_audited_http.<locals>.audited	  s@    )	 )	 )	 )	 )	 )	 )	 )	 )	 )	V r2   )r   r   	functoolsr5  typingr    r   )r3  	_CallablerT  rL  rM  r5  s   `  @@@r   _make_audited_httprX  	  s    
 )(((((((((((,,,,,,<E 4 4 4 4sTz 4 4 4 4 4 4 4 4 4l Nr2   Tr  initialize_memoryhttp_extensionc           	      ^    8t          dt                    r!t          j        dj        j                    t          dt          f fd            }ddlm	} ddl
m}  |            }t          d	|d
ddiddd||j                   j        _         j        j        _        j        dt"          t$          t&          f         ffd}|_                            d          fd            }                    d          d             }	t+                     r                               }
                    |
ddg           t          j        d                                          }|r)                    |           t          j        d           S )a)  
    Create and configure the FastAPI application.

    Args:
        memory: MemoryEngine instance (already initialized with required parameters).
                Migrations are controlled by the MemoryEngine's run_migrations parameter.
        initialize_memory: Whether to initialize memory system on startup (default: True)
        http_extension: Optional HTTP extension to mount custom endpoints under /extension/.
                       If None, attempts to load from HINDSIGHT_API_HTTP_EXTENSION env var.

    Returns:
        Configured FastAPI application

    Note:
        When mounting this app as a sub-application, the lifespan events may not fire.
        In that case, you should call memory.initialize() manually before starting the server
        and memory.close() when shutting down.
    NHTTPzLoaded HTTP extension: appc           
       K   ddl }ddl}ddlm} ddlm}  |            }d}d}	 t          dd          }t                       || j        _	        t          j        d           n;# t          $ r.}	t          j        d	|	 d
           d| j        _	        Y d}	~	nd}	~	ww xY w|j        r|j        st          j        d           nddlm}
m} 	  ||j        |j        |j        |j                    |
             t          j        d           nB# t          $ r5}	t          j        d|	            t          j        d           Y d}	~	nd}	~	ww xY wr                                 d{V  t          j        d           t1                      }j        >t5          |d          r.|                    j                   t          j        d           |j        rj        j        rddlm } |j!        p|"                                }|j#        |k    rdn|j#        } |j        |j$        |j%        |j&        |j'        |j(                  } |j)        |*                                          }t          j        d| d           n'|j        r j        j        st          j        d           j+        }|r.|,                                 d{V  t          j        d           r.,                                 d{V  t          j        d           dW V  |`|-                    d           d{V  |.|.                                 	 | d{V  n# |j/        $ r Y nw xY wt          j        d           |r.|0                                 d{V  t          j        d           r.0                                 d{V  t          j        d            1                                 d{V  t          j        d!           dS )"z
        Lifespan context manager for startup and shutdown events.
        Note: This only fires when running the app standalone, not when mounted.
        r   Nr3   )WorkerPollerzhindsight-apiz1.0.0)service_nameservice_versionz4Metrics initialized - available at /metrics endpointzFailed to initialize metrics: z3. Metrics will be disabled (using no-op collector).zBOTEL tracing enabled but no endpoint configured. Tracing disabled.)create_span_recorderinitialize_tracing)r`  endpointheadersdeployment_environmentz,OpenTelemetry tracing enabled and configuredzFailed to initialize tracing: zContinuing without tracingzMemory system initializedset_db_poolzDB pool metrics configuredrx   )DEFAULT_DATABASE_SCHEMA)backend	worker_idexecutorpoll_interval_msschematenant_extension	max_slotsslot_reservationsz!Worker poller started (worker_id=)u   Worker poller disabled — backend does not support async operations. Tasks (mental model refresh, consolidation) will run synchronously.zTenant extension startedzHTTP extension startedg      >@)timeoutzWorker poller stoppedzTenant extension stoppedzHTTP extension stoppedzMemory system closed)2asynciosockethindsight_api.configr4   hindsight_api.workerr_  rD   rB   stateprometheus_readerlogginginfo	Exceptionwarningotel_traces_enabledotel_exporter_otlp_endpointhindsight_api.tracingrb  rc  otel_service_nameotel_exporter_otlp_headersotel_deployment_environmenterror
initializerC   _poolrC  rg  worker_enabled_backendsupports_worker_pollerr  rh  rj  gethostnamedatabase_schemaexecute_taskworker_poll_interval_ms_tenant_extensionworker_max_slotsworker_slot_reservationscreate_taskrunrn  
on_startupshutdown_gracefulcancelCancelledErroron_shutdownclose)r]  rs  rt  r4   r_  r  pollerpoller_taskrx  r  rb  rc  metrics_collectorrh  rj  rm  rn  rZ  rY  r  s                    r   lifespanzcreate_app.<locals>.lifespan
  sf      	333333555555	/ 2ah i i i$&&&*;CI'LOPPPP 	/ 	/ 	/OsQsssttt*.CI''''''	/ % 	B5 B deeeeZZZZZZZZB&&%+%=!'!C & A/5/Q	    )(***L!OPPPP  B B BM"F1"F"FGGGO$@AAAAAAAAB
  	;##%%%%%%%%%L4555 !6 7 7|'G4E},U,U'!--fl;;;9:::   	V_%K 	888888(@F,>,>,@,@I#37NNNTTTZTjF!\#,!'!?!'!9 1"("A	 	 	F .'-fjjll;;KLIYIIIJJJJ" 	6?+Q 	OV   "2 	5"--/////////L3444  	3 ++---------L1222 **4*888888888&""$$$%%%%%%%%%-   DL0111  	5"..000000000L3444  	3 ,,.........L1222 llnn+,,,,,sB   ?A' '
B1$BBAD 
E+E

EM 
M'&M'r   __version__r3   zHindsight HTTP APIzHTTP API for Hindsightr[  zMemory Systemz
Apache 2.0z0https://www.apache.org/licenses/LICENSE-2.0.html)r[  r  )r   r  rJ   contactlicense_infor  	root_pathr   c                                  } |                      di                                di                                d          }|rAd|                     di           vr)ddi|d         d<   dd	d
|d         d<   ddd
|d         d<   | S )N
componentsschemasValidationErrorra  r@  r   InputContextr:  )r   r   ctxURLr;  r  )r+  )rm  ve_original_openapis     r   _patched_openapiz$create_app.<locals>._patched_openapi
  s    ""$$ZZb))--i<<@@ARSS 	I'b!9!999)0'(:B|W%098&L&LB|U#05x&H&HB|U#r2   r=  c                   K   ddl }ddlm} g }| j        rj        D ]}|                    | j                  \  }}||j        k    rt          |dd          }|r|	                    |          }	t          |	j                                                  }
t          t          |di                                                     t          | j                                                  z  }|
|z
  }| j        D ]}||vr||vr|                    |             ng }| j                            dd          }| j        dv rd	|v r	 |                                  d{V }|rlt'          j        |          }t+          |t,                    rBj        D ]9}|                    | j                  \  }}||j        k    rt          |dd          }|r|	                    |          }	|	j                                        D ]}|j        }t+          |t2                    rt5          |t6                    rt          |j                                                  }|j                                        D ]6}t+          |j        t<                    r|                    |j                   7|D ]}||vr|                    |            n n;n# t&          j         tB          f$ r Y nw xY w||z   } ||            d{V }|rKd
"                    |          }tF          $                    d|| j        | j%        j&                   ||j        d<   |S )zQDetect unknown query params and body fields, log warning and set response header.r   N)Matchrd  param_convertorszcontent-typer   )POSTPUTPATCHzapplication/jsonz, z*Unknown parameters ignored: [%s] for %s %szX-Ignored-Params)'rP  starlette.routingr  query_paramsroutesmatchesrg  FULLr  rQ  r  
parameterskeyspath_paramsr   re  r+  methodbodyr   r   r   r   values
annotationr   
issubclassr!   model_fieldsr  r   addr   UnicodeDecodeErrorjoinloggerr|  r  path)r6  	call_nextrP  r  ignored_paramsrouter^  _rd  sigdeclaredr  known_queryr[  body_ignoredcontent_type
body_bytes	body_jsonparamannknown_fieldsfieldkeyall_ignoredrD  ignored_strr]  s                             r   unknown_params_middlewarez-create_app.<locals>.unknown_params_middleware
  s      	++++++$&  	   ==77qEJ&&&uj$??H 	<%//99#&s~':':'<'<#=#=&)'%9KR*P*P*U*U*W*W&X&X[^#/4466\ \ ' '/&<$+$8 < <D#;664{;R;R . 5 5d ; ; ;E ' #%**>2>>>555:LP\:\:\#*<<>>111111
 & $
: 6 6I!)T22 &%(Z & &E',}}W]'C'CHE1$
22+25*d+K+K#+ !2*1*;*;H*E*EC141F1F1H1H %2 %2.3.>+5c4+@+@ )2ZPSU^E_E_ )2;>s?O?T?T?V?V;W;WL9<9I9P9P9R9R -R -R
 4>ek33O3O 1R4@4D4DU[4Q4Q4Q7@ -M -M36l3J3J4@4G4G4L4L4L,1E %'  3( (*<=    %|3"7++++++++ 	?))K00KNN< 	   4?H/0s   
F	K K-,K-c                 J  K   ddl }ddlm} | j        j        } |j        dd|          } |j        dd|          }dgt                      }|                    | j        |fd          5   ||            d{V }|j	        d<   |cddd           S # 1 swxY w Y   dS )	zRecord HTTP request metrics.r   N)r   z=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}z/{id}z/\d+(?=/|$)rH   c                       d         S )Nr   r+   )status_codes   r   <lambda>z=create_app.<locals>.http_metrics_middleware.<locals>.<lambda>  s    Q\]^Q_ r2   )
r]  starlette.requestsr   r  r  subrC   record_http_requestr  r  )r6  r  r]  r   r  r  rD  r  s          @r   http_metrics_middlewarez+create_app.<locals>.http_metrics_middleware  s&     
 				......{rvVX_aeffrvngt44e133227>4I_I_I_I_`` 	 	&Yw////////H%1KN	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s   .BBBz/ext	Extension)prefixro   z&HTTP extension router mounted at /ext/z"HTTP extension root router mounted)rA   r?   ry  rz  	__class__rM   r   r	   hindsight_apir  ru  r4   	base_pathrw  r  audit_loggeropenapir   r   r   
middleware_register_routes
get_routerinclude_routerget_root_router)r  rY  rZ  r  r  r4   r  r  r  r  extension_routerroot_routerr  r]  s   ```         @@r   
create_appr  	  s\   0 '>> 	XLV>3K3TVVWWWw-G w- w- w- w- w- w- w- w-r *)))))//////Z\\F
",O
 !E
 
 "  C" CI#0CI d38n       #CK 	^^FJ J J J JZ 	^^F  . S  	?)44V<<+F+OOO=>>> %44V<< 	?{+++L=>>>Jr2   r]  c                 8   HI t           fd          }t          d          fdt          dz  dt          fd}                     t
                    dt
          fd            }                     d	d
ddg           fd            }                     dt          dddgd          dt          fd            }                     ddddg          d             }                     dt          ddddg          dddt          d          d ddt          |          fd!t          d"t          dz  d#t          d$t          dz  d%t          t                   dz  d&t          d't          dz  d(t          dz  d)t          f fd*            }                     d+t          d,d-d.dg          dddd/d0t          |          fd!t          d"t          dz  d$t          dz  d1t          dz  d#t          d2t          d)t          f fd3            }                     d4d5d6d7dg8          t          |          fd!t          d9t          d)t          f fd:            }	                     d;d<d=d>dg8          t          |          fd!t          d9t          d)t          f fd?            }
                     d@t          dAdBdCdg           |dD          t          |          fd!t          dEt           d)t          f fdF                        }                     dGt"          dHdIdJdg           |dJ          t          |          fd!t          dEt$          d)t          f fdK                        }                     dLt&          dMdNdOdPg          t          |          fd)t          f fdQ            }                     dRt(          dSdTdUdPg          t          |          fd!t          d)t          f fdV            }                     dWt*          dXdYdZdPg          d[t          d\d]^          t          |          fd!t          d_t          d`t          d)t          f fda            }                     dbt,          dcdddedfg          t          d/dg^          t          d0dh^          t          |          fd!t          d#t          d2t          d)t          f fdi            }                     djt.          dkdldmdfg          t          ddn^          t          dodp^          t          |          fd!t          d#t          dqt          d)t          f fdr            }                     dst0          dtdudvdfg          t          |          fd!t          dwt          d)t          f fdx            }                     dyt0          dzd{d|dfgd}~          t          |          fd!t          dwt          d)t          fd            }                     dt2          ddddg          t          dd%d          t          dd          t          dd          t          d/dod          t          d0d0          t          |          fd!t          dt          t                   dz  d&t4          d         dt4          d         d#t          d2t          d)t          f fd            }                     dt6          ddddg          t          dd          t          |          fd!t          dt          dt4          d         d)t          f fd            }                     dddddg8          t          |          fd!t          dt          d)t          f fd            }                     dt8          ddddg           |dd          t          |          fd!t          dt:          d)t          f fd                        }                     dt<          ddddg           |dd          t          |          fd!t          dt          d)t          f fd                        }                     dt6          ddddg           |dd          t          |          fd!t          dt          dt@          d)t          f fd                        } !                    dddddg8           |dd          t          |          fd!t          dt          d)t          f fd                        }                     dtD          ddddg          t          dd%d          t          dd          t          d}d          t          d/dod          t          d0d0          t          |          fd!t          dt          t                   dz  d&t4          d         dtF          d#t          d2t          d)t          f fd            }                     dtH          ddddg          t          |          fd!t          dt          d)t          f fd            }                     dtH          ddddg           |dd          t          |          fd!t          dtJ          d)t          f fd                        }                     dtH          ddddg           |dd          t          |          fd!t          dt          dtL          d)t          f fdƄ                        } !                    dddddg8           |dd          t          |          fd!t          dt          d)t          f fdʄ                        }                     dtN          ddddg          t          ddЬ          t          ddѬ          t          ddӬ          d/d0t          |          fd!t          d$t          dz  d%t          t                   dz  d&t          d#t          d2t          d)t          f fdԄ            }                      dtP          ddddg          t          d/dodd٬ڦ          t          d0d0dhۦ          t          |          fd!t          d't          d#t          d2t          d)t          f
 fd܄            }!                     dtR          ddddg           |d          t          |          fd!t          d't          d)t          f fd                        }"                     dtT          ddddg          t          |          fd!t          d't          d)t          f fd            }#                     dtV          ddddg          t          dd^          t          dd^          t          d/d^          t          d0dh^          t          |          fd!t          d$t          dz  dt4          d         d#t          d2t          d)t          f fd            }$                     dtX          ddddg          t          |          fd(t          d)t          f fd            }%                     dtZ          ddddg           |dd          t          |          fd!t          d't          dt\          d)t          f fd                        }& !                    dt^          ddddg           |dd          t          |          fd!t          d't          d)t          f fd                        }'                     dt`          d dddg          t          dd^          t          dd^          t          ddod/dڦ          t          d0d0dۦ          t          d	d
^          t          |          fd!t          dt          dz  d"t          dz  d#t          d2t          dtF          d)t          f fd            }(                     dtb          ddddg          t          d	d^          t          |          fd!t          dt          dtF          d)t          f fd            }) !                    dtd          ddddg           |dd          t          |          fd!t          dt          d)t          f fd                        }*                     dtf          ddddg           |dd          t          |          fd!t          dt          d)t          f fd                        }+                     dth          d d!d"dPgd}~          t          |          fd!t          d)t          f fd#            }, 5                    dth          d$d%d&dPgd}~          t          |          fd!t          dEtl          d)t          f fd'            }-                     d(tn          d)d*d+dPgd}~          t          |          fd!t          dEtp          d)t          f fd,            }. 5                    d-th          d.d/d0dPg           |d1          t          |          fd!t          dEtr          d)t          f fd2                        }/                     d-th          d3d4d5dPg           |d5          t          |          fd!t          dEtr          d)t          f fd6                        }0 !                    d-tt          d7d8d9dPg           |d9d          t          |          fd!t          d)t          f fd:                        }1                     d;tv          d<d=d>d?g           |d>d          t          d	d@^          t          |          fd!t          dEtx          dAtF          d)t          f fdB                        }2                     dCtz          dDdEdFd?g          t          |          fd!t          d)t          f fdG            }3                     dHdIdJdKd?g8          dL             }4 !                    dMtt          dNdOdPdPg           |dPd          t          |          fd!t          d)t          f fdQ                        }5                     dRt|          dSdTdUdPg           |dUd          t          |          fd!t          d)t          f fdV                        }6 !                    dWt~          dXdYdZdg           |dZd          t          |          fd!t          d9t          d)t          f fd[                        }7                     d\t          d]d^d_dPg          t          |          fd!t          d)t          f fd`            }8                     d\t          dadbdcdPg           |dc          t          |          fd!t          dEt          d)t          f fdd                        }9 !                    d\t          dedfdgdPg           |dgd          t          |          fd!t          d)t          f fdh                        }:                     dit          djdkdldPg           |dmd          t          |          fd!t          d)t          f fdn                        };                     dot          dpdqdrdsgdtu           |dr          t          |          fd!t          dEt          d)t          f fdv                        }<                     dot          dwdxdydsg          t          |          fd!t          d)t          f fdz            }= !                    d{tt          d|d}d~dsg           |d~d          t          |          fd!t          dt          d)t          f fd                        }>                     d{t          ddddsg           |d          t          |          fd!t          dt          dEt          d)t          f fd                        }?                     dt          ddddsg          t          ddd          t          dd^          t          |          fd!t          dt          d#t          dt          dz  d)t          f
 fd            }@                     dt          ddddg           |d          t          |          fd!t          dEt          d)t          f fd                        }A                     dt          ddddg           |dd          t          dd          t          dd          t          |          fd!t          dt          t                   dEt          d)t          f fd                        }B !                    dtt          ddddg           |dd          t          dd          t          |          fd!t          d"t          dz  d)t          f fd                        }C G d dt                    H G Hfddt                    }D G d dt                    I G Ifddt                    }E                     dddddg|D          t          dd          t          dd          t          dd          t          dd          t          ddodd          t          d0d0dh          t          |          fd!t          dt          dz  dt          dz  dt          dz  dt          dz  d#t          d2t          d)t          f fd            }F                     dddÐdĐdg|E          t          dd          t          d[dŬ          t          |          fd!t          dt          dz  d_t          d)t          f fdƄ            }GdS (  z2Register all API routes on the given app instance.c                  0    t           j        dd           S )Nr  )r  rw  )r]  s   r   r  z"_register_routes.<locals>.<lambda>4  s    ND)Q)Q r2   NrA  authorizationr   c                     d}| rX|                                                      d          r| dd                                         }n|                                 }t          |          S )a   
        Extract request context from Authorization header.

        Supports:
        - Bearer token: "Bearer <api_key>"
        - Direct API key: "<api_key>"

        Returns RequestContext with extracted API key (may be None if no auth header).
        Nzbearer    )api_key)r  
startswithr  rE   )r  r  s     r   get_request_contextz-_register_routes.<locals>.get_request_context6  sq      	0""$$//	:: 0'+1133'--//g....r2   excc                 J   K   ddl m}  |ddt          |          i          S )Nr   JSONResponsei  detail)r  r   )fastapi.responsesr  r   )r6  r  r  s      r   authentication_error_handlerz6_register_routes.<locals>.authentication_error_handlerI  sB      222222|s3xx(
 
 
 	
r2   z/healthzHealth check endpointz4Checks the health of the API and database connection
Monitoring)r>  rJ   ro   c                     K   ddl m}  j        j                                         d{V }|                    d          dk    rdnd} | ||          S )	z
        Health check endpoint that verifies database connectivity.

        Returns 200 if healthy, 503 if unhealthy.
        r   r  Nr  healthyr  i  )r   r  )r  r  rw  r  health_checkr+  )r  healthr  r]  s      r   health_endpointz)_register_routes.<locals>.health_endpointR  sw       	322222y'4466666666#ZZ11Y>>ccC|FDDDDr2   z/versionz!Get API version and feature flagszReturns API version information and enabled feature flags. Use this to check which capabilities are available in this deployment.get_version)response_modelr>  rJ   ro   r)  c            
         K   ddl m}  ddlm}  |            }t	          | t          |j        |j        |j        |j	        |j
                            S )aI  
        Get API version and enabled features.

        Returns version info and feature flags that can be used by clients
        to determine which capabilities are available.

        Note: observations flag shows the global default. Individual banks
        may override this setting via bank-specific configuration.
        r   r  )_get_raw_configr  r  )r  r  ru  r  r  r  r  mcp_enabledr  enable_bank_config_apienable_file_upload_api)r  r  r  s      r   version_endpointz*_register_routes.<locals>.version_endpointd  s      & 	.-----888888 ""#!#7&, & = & =  	
 	
 	
 		
r2   z/metricszPrometheus metrics endpointz1Exports metrics in Prometheus format for scrapingc                  P   K   ddl m}  ddlm}m}  |            } | ||          S )zReturn Prometheus metrics.r   )Response)CONTENT_TYPE_LATESTgenerate_latest)r   
media_type)r  r  prometheus_clientr  r  )r  r  r  metrics_datas       r   metrics_endpointz*_register_routes.<locals>.metrics_endpoint  sU       	/.....JJJJJJJJ&((x9LMMMMr2   z!/v1/default/banks/{bank_id}/graphzGet memory graph dataz^Retrieve graph data for visualization, optionally filtered by type (world/experience/opinion).	get_graphMemory)r  r>  rJ   r)  ro   r   
all_strictr$  r   r   qro   rp   r   r   r  c	                   K   	 j         j                            | ||||||||	  	         d{V }	|	S # t          $ r }
t	          |
j        |
j                  d}
~
wt          t          f$ r  t          $ rm}
ddl	}t          |
           d|                                 }t                              d|  d|            t	          dt          |
                    d}
~
ww xY w)	zIGet graph data from database, filtered by bank_id and optionally by type.)r   r  ro   rp   r   r   r  Nr  r  r   

Traceback:
Error in /v1/default/banks/z/graph: rH   )rw  r  get_graph_datar@   r   r  reasonr   r{  	tracebackr   
format_excr  r  )r$  r   r   r  ro   rp   r   r   r  r   r  r  error_detailr]  s                r   	api_graphz#_register_routes.<locals>.api_graph  sF     (	@)88%'! / 9 
 
 
 
 
 
 
 
D K' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLVwVVVVWWWCA????	@s!   /5 
C%AC%8A(C  C%z)/v1/default/banks/{bank_id}/memories/listzList memory unitszList memory units with pagination and optional full-text search. Supports filtering by type. Results are sorted by most recent first (mentioned_at DESC, then created_at DESC).list_memoriesr   r   consolidation_stater   c           	      "  K   	 j         j                            | ||||||           d{V }|S # t          $ r#}t	          dt          |                    d}~wt          $ r }t	          |j        |j                  d}~wt          t          f$ r  t          $ rm}ddl}	t          |           d|	                                 }
t                              d|  d|
            t	          d	t          |                    d}~ww xY w)
a  
        List memory units for table view with optional full-text search.

        Results are ordered by most recent first, using mentioned_at timestamp
        (when the memory was mentioned/learned), falling back to created_at.

        Args:
            bank_id: Memory Bank ID (from path)
            type: Filter by fact type (world, experience, opinion)
            q: Search query for full-text search (searches text and context)
            consolidation_state: Filter by consolidation state for source memories
                (world/experience). One of 'failed', 'pending', or 'done'.
            limit: Maximum number of results (default: 100)
            offset: Offset for pagination (default: 0)
        )r$  	fact_typesearch_queryr#  r   r   r  N  r  r   r  r  z/memories/list: rH   )rw  r  list_memory_unitsr{   r   r   r@   r  r  r   r{  r  r  r  r  )r$  r   r  r#  r   r   r  r   r  r  r   r]  s              r   api_listz"_register_routes.<locals>.api_list  st     @	@);;$7 / <        D K 	@ 	@ 	@CA????' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL^w^^P\^^___CA????	@s-   -3 
DAD(BD!A(D		Dz0/v1/default/banks/{bank_id}/memories/{memory_id}zGet memory unitzGet a single memory unit by ID with all its metadata including entities and tags. Note: the 'history' field is deprecated and always returns an empty list - use GET /memories/{memory_id}/history instead.
get_memory)r>  rJ   r)  ro   	memory_idc           	      N  K   	 j         j                            | ||           d{V }|t          dd| d          |S # t          $ r }t          |j        |j                  d}~wt          $ r#}t          dt          |                    d}~wt          t          f$ r  t          $ rp}ddl}t          |           d	|                                 }t                              d
|  d| d|            t          dt          |                    d}~ww xY w)zGet a single memory unit by ID.r$  r+  r  N  Memory unit '' not foundr  r'  r   r  r  
/memories/: rH   )rw  r  get_memory_unitr   r@   r  r  r{   r   r   r{  r  r  r  r  r$  r+  r  r   r  r  r   r]  s          r   api_get_memoryz(_register_routes.<locals>.api_get_memory  s     	@)99# / :        D
 |#<bI<b<b<bccccK' 	L 	L 	LAM!(KKKK 	@ 	@ 	@CA????#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLewee)eeWceefffCA????	@s1   A A 
D$A++D$8BD$4A+DD$z8/v1/default/banks/{bank_id}/memories/{memory_id}/historyzGet observation historyz_Get the full history of an observation, with each change's source facts resolved to their text.get_observation_historyc           	        K   	 j         j                            | ||           d{V }|t          dd| d          |S # t          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}ddl	}t          |           d|                                 }t                              d	|  d
| d|            t          dt          |                    d}~ww xY w)z.Get the history of a single observation by ID.r-  Nr.  r/  r0  r  r   r  r  r1  
/history: rH   )rw  r  r6  r   r@   r  r  r   r{  r  r   r  r  r  r4  s          r   api_get_observation_historyz5_register_routes.<locals>.api_get_observation_history  sb     	@)AA# / B        D
 |#<bI<b<b<bccccK' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLmwmm)mm_kmmnnnCA????	@s%   A A 
C9A++C9	A+C44C9z+/v1/default/banks/{bank_id}/memories/recallzRecall memorya$  Recall memory using semantic similarity and spreading activation.

The type parameter is optional and must be one of:
- `world`: General knowledge about people, places, events, and things that happen
- `experience`: Memories about experience, conversations, actions taken, and tasks performedrecall_memoriesrt  r6  c                 
  $K   ddl }|                                 }t                      }t                      j        }t	                      }t          |                    |j                            }||k    rt          dd| d| d          	 |j	        r|j	        nt          t                    }	d}
|j        rb	 t          j        |j                            dd	                    }
n3# t           $ r&}t          dd
t#          |                     d}~ww xY w|j        j        du}|r|j        j        j        nd}|j        j        du}|r|j        j        j        nd}|j        j        du}|r|j        j        j        nd}|r|j        j        j        nd}|                                 |z
  }|                    d| d|j        j        |j                  5  |                                 }%j        j                            | |j        |j        |j        |j        |	|
|||||||||j        |j         |j!                   d{V }ddd           n# 1 swxY w Y   dddtD          fd$$fd|j#        D             }d}|j        rFi }|j        $                                D ]*\  }}tK          ||j&        |j'        |j(                  ||<   +d}|j        rOi }|j        $                                D ]3\  }}tS          |j*        |j+        d |j,        D                       ||<   4d}|j        r%$fd|j        $                                D             }t[          ||j        |||          }|                                 |z
  }|                                 |z
  } ||z
  | z
  }!|dk    rKt]          j/        d|  d|d d!|d d"| d d#|!d d$t          |           d%|rt          |          nd            |S # t          $ r  t`          $ r }t          |j1        |j2                  d}~wtf          t          f$ r  th          j5        tj          f$ rK |                                 |z
  }tl          7                    d&|  d'|d d(           t          d)d*          tp          $ r}ddl9}"|                                 |z
  }t#          |           d+|":                                 }#tl          7                    d,|  d'|d d-t#          |           d.|#            t          dt#          |                    d}~ww xY w)/z+Run a recall and return results with trace.r   Nr'  zQuery too long: z tokens exceeds maximum of z. Please shorten your query.r  r   r  zSInvalid query_timestamp format. Expected ISO format (e.g., '2023-05-30T23:40:00'): rH   rU   rX   rY   rt  api)r$  r   rk   rK   )r$  ri   rk   rK   enable_tracer%  question_dateinclude_entitiesmax_entity_tokensr9  max_chunk_tokensinclude_source_factsmax_source_facts_tokens'max_source_facts_tokens_per_observationr  ro   rp   ru   r  r;   r   c                     t          | j        | j        | j        | j        | j        | j        | j        | j        | j	        | j
        | j        | j        | j                  S )N)r   r   r   r]   r   r   r   r   r   r   r   ro   r   )r   r   r   r%  r]   r   r   r   r   r   r   r   ro   r   )r  s    r   _fact_to_resultz=_register_routes.<locals>.api_recall.<locals>._fact_to_result  s_    #w!] L#'#6!%!2!%!2 $ 0!]!]$($8   r2   c                 &    g | ]} |          S r+   r+   )r{  r  rF  s     r   r  z8_register_routes.<locals>.api_recall.<locals>.<listcomp>  s#    TTTood33TTTr2   )r   r   r   r   c                 D    g | ]}t          |j        |j                   S r   r   r   r   r{  obss     r   r  z8_register_routes.<locals>.api_recall.<locals>.<listcomp>  s;     & & & # 638RURbccc& & &r2   r   c                 .    i | ]\  }}| |          S r+   r+   )r{  fact_idr  rF  s      r   r}  z8_register_routes.<locals>.api_recall.<locals>.<dictcomp>  s6     ) ) )7DwG__T22) ) )r2   )r   rl   r]   r^   r_   g      ?z[RECALL HTTP] bank=z handler_total=z.3fzs pre=z	s recall=zs post=z
s results=z
 entities=z[RECALL TIMEOUT] bank=z handler_duration=zs - database query timed out  zQRequest timed out while searching memories. Try a shorter or more specific query.r  z[RECALL ERROR] bank=zs error=
);r  rC   r4   recall_max_query_tokensr7   rO  encoderi   r   rj   r,   r:   rm   r   r  r   r{   r   rn   r]   rK   r^   r_   rZ   record_operationrk   r  rw  r  recall_asyncrl   ro   rp   ru   r   r   r   r   r  r   r   r   r   r   r   r   ry  rz  r@   r  r  r   rs  TimeoutErrorr  r  r{  r  r  )&r$  r6  r  r  handler_startmetricsmax_query_tokensencodingquery_tokensrG  r>  r  r?  r@  r9  rA  rB  rC  rD  
pre_recallrecall_startcore_resultrecall_resultschunks_responser   
chunk_infoentities_responser[  rw  source_facts_responserD  handler_durationrecall_durationpost_recallr  r   rF  r]  s&                                       @r   
api_recallz$_register_routes.<locals>.api_recall<  s^       			')) &<<?)++8??7=99::*** B,  B  BSc  B  B  B   
X	@*1-ZTBY=Z=ZJ !M& $,$:7;R;Z;Z[^`h;i;i$j$jMM!   '$'}uxyzu{u{}}     '7tCGW ` 8 C C]` %_34?NDR\w5@@X\ $+?#?t#K Qe&ogo&B&M&Mko#K_g,GGeg 4 }4J))'%@Tahas *      $yy{{$'I$4$A$A#!-">&1!(("/%5&7#1%5)=,C<c$3 &1&1% %B % %      	              4l |    " UTTT@STTTN #O! "$,7,>,D,D,F,F  (Hj09#'2$.$:","6	1 1 1OH-- !%# 
$&!#.#7#=#=#?#?  KD%.A"'/',';& &','9& & &/ / /%d++ %)!' ) ) ) )HSH`HfHfHhHh) ) )% &&!'*&2  H  $yy{{]:"iikkL8O*Z7/IK#%%s' s sBRZ s s%cs s4Ccs sP[cs s">22s sXi>pcBS>T>T>Tops s   O 	 	 	' 	L 	L 	LAM!(KKKK#]3 	 	 	$l3 	 	 	#yy{{]:LLvvvDTvvvv    j     	@ 	@ 	@#yy{{]:!!ffNNi6J6J6L6LNNLLLxwxxBRxxx`cde`f`fxxjvxx    CA????	@sq   +O: >-C, +O: ,
D6!DDCO: A/IO: IO: I FO: :T>P))A=T>&BT99T>z#/v1/default/banks/{bank_id}/reflectzReflect and generate answeraS  Reflect and formulate an answer using bank identity, world facts, and opinions.

This endpoint:
1. Retrieves experience (conversations and events)
2. Retrieves world facts relevant to the query
3. Retrieves existing opinions (bank's perspectives)
4. Uses LLM to formulate a contextual answer
5. Returns plain text answer and the facts usedreflectc                   K   t                      }	 |j        }|j        r|j         d|j         }|                    d| d|j        j                  5  j        j                            | ||j        d |j	        |j
        ||j        |j        |j        |j        |j        |j                   d {V }d d d            n# 1 swxY w Y   d }|j        j        g }g }g }	|j                                        D ]\  }
}|
dk    r=|D ]9}|	                    t-          |d         |d         |d	         
                     :H|
dk    r:|D ]6}|                    t/          |j        |j        |j                             7|D ]H}|                    t5          |j        |j        |j        |j        |j        |j                             It=          |||	          }d }|j        j        F|j        j        j         fd|j!        D             }d |j"        D             }tG          ||          }tI          |j        ||j%        |j&        |          S # tN          $ r }tQ          |j)        |j*                  d }~wtV          tP          f$ r  tX          $ r#}tQ          dt[          |                    d }~wt\          $ rA}t^          0                    d| |           tQ          dt[          |          pd          d }~wtb          $ rm}dd l2}t[          |           d|3                                 }t^          0                    d|  d|            tQ          dt[          |                    d }~ww xY w)Nz

Additional context: rg  r<  )r$  r   rk   )r$  ri   rk   r   rK   rB  r  ro   rp   ru   rG  rI  rK  rl  r   r[  r   )r   r[  r   zmental-models)r   r   r   rX  )rj  rk  rl  c           	      r    g | ]3}t          |j        |j        r|j        nd |j        |j                  4S )N)r`  ra  r2  rc  rd  )r_  r`  ra  r2  rc  rd  )r{  tcinclude_outputs     r   r  z9_register_routes.<locals>.api_reflect.<locals>.<listcomp>N  s\     	 	 	  $W h,:Dryy$&N"$,  	 	 	r2   c                 D    g | ]}t          |j        |j                   S )rw  )rf  rg  rc  )r{  lcs     r   r  z9_register_routes.<locals>.api_reflect.<locals>.<listcomp>X  s*    xxx\^^"(WWWxxxr2   )r6  ro  r{  r  r'  z+Timeout in /v1/default/banks/%s/reflect: %srO  zSReflect operation timed out. Consider reducing the budget or simplifying the query.r   r  r  z
/reflect: rH   )4rC   ri   r   rS  rk   r  rw  r  reflect_asyncrK   rB  ro   rp   ru   rG  rI  rK  rn   r5  r|  r   r   rZ  r]  r   r   rV  r%  r   r   ri  r6  r2  
tool_trace	llm_tracern  rq  r}  r&  r@   r   r  r  r   r9   r   rU  r  r  r{  r  r  )r$  r6  r  rW  ri   r]  based_on_resultrj  rk  rl  r%  r5  r  r  trace_resultr6  ro  r  r  r   rk  r]  s                       @r   api_reflectz%_register_routes.<locals>.api_reflect  s     $ ())n	@ME T"=SS'/SS )))WU[b[i[o)pp  $'I$4$B$B#"> &1$+$;$3 &1&1&1*1*G-4-M %C % %                    $ 6:O$0 "
(3(<(B(B(D(D    $Iu L00).  I&-- 0'0)26):,5i,@!" !" !"    #o55$)  D)00 2'+w)-,0L!" !" !"    %* 
 
D$OO +'+w)-)-,0L373F151B!" !" !"	 	 	 	
 #1(R_lv"w"w"w 15L)5!(!;!B	 	 	 	 *4	 	 	
 yxbmbwxxx	+)'     
 # %("-"?!'"    ( 	L 	L 	LAM!(KKKK#]3 	 	 	# 	@ 	@ 	@CA???? 	 	 	LLFQRSSS1vvv!v     	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLXwXX,XXYYYCA????	@sc   AI A C6I CI 	C
FI 
M<"I==M<J99M<<LM<A(M77M<z/v1/default/bankszList all memory banksz,Get a list of all agents with their profiles
list_banksBanksc                   K   	 j         j                            |            d{V }t          |          S # t          t
          f$ r  t          $ rj}ddl}t          |           d|	                                 }t                              d|            t          dt          |                    d}~ww xY w)	z*Get list of all banks with their profiles.r  N)r  r   r  zError in /v1/default/banks: rH   r  )rw  r  rt  r  r   r   r{  r  r   r  r  r  )r  r  r  r  r   r]  s        r   api_list_banksz(_register_routes.<locals>.api_list_banksy  s      
	@)*55o5VVVVVVVVE#%0000#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLFFFGGGCA????	@s   5; C A%B;;C z!/v1/default/banks/{bank_id}/statszGet statistics for memory bankz9Get statistics about nodes and links for a specific agentget_agent_statsc                   K   	 j         j                            | |           d{V }|d         }|d         }|d         }i }|d         D ]*}|d         }||vri ||<   |d         ||         |d	         <   +|d
         }	t          | t	          |                                          t	          |                                          |d         |||||	                    dd          |	                    dd          |	|d         |d         |                    dd          |d                   S # t          $ r }
t          |
j	        |
j
                  d}
~
wt          t          f$ r  t          $ rm}
ddl}t          |
           d|                                 }t                               d|  d|            t          dt          |
                    d}
~
ww xY w)z>Get statistics about memory nodes and links for a memory bank.rw  Nnode_countslink_countslink_counts_by_fact_typelink_breakdownr%  r  	link_typer  r  r  r   r  r  r  r  r  )r$  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  z/stats: rH   )rw  r  get_bank_statsr  sumr  r+  r@   r   r  r  r   r{  r  r   r  r  r  )r$  r  statsnodes_by_typelinks_by_typer  r  r(  ftopsr  r  r   r]  s                r   	api_statsz#_register_routes.<locals>.api_stats  sH     &	@)*99'Sb9ccccccccE!-0M!-0M!&'A!B9;O-. E E%_,,*,OB'8;G#C$455%C$ 4 4 6 677 4 4 6 677 %&7 8#0#0#5 /#&779a#8#8"%''(A"6"6%(%*+A%B&+,C&D%*YY/Eq%I%I#()=#>   " ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLVwVVVVWWWCA????	@s%   D+D1 1
G!;EG!4A(GG!z5/v1/default/banks/{bank_id}/stats/memories-timeserieszMemory ingestion time-serieszOMemories ingested over a period, bucketed by time and broken down by fact type.get_memories_timeseries7dr  a  Timestamp column to bucket on. `created_at` (default) = ingest time; `mentioned_at` / `occurred_start` = event time, useful for migrated corpora where ingest time is a single point and doesn't reflect the underlying knowledge timeline. Unknown values fall back to `created_at`.rI   r!  r#  c                   K   	 j         j                            | |||           d {V }t          di |S # t          $ r }t          |j        |j                  d }~wt          t
          f$ r  t          $ rm}dd l
}t          |           d|                                 }t                              d|  d|            t          dt          |                    d }~ww xY w)	N)r!  r#  r  r  r   r  r  z/stats/memories-timeseries: rH   r+   )rw  r  r  r   r@   r   r  r  r   r{  r  r   r  r  r  )	r$  r!  r#  r  r   r  r  r   r]  s	           r   api_memories_timeseriesz1_register_routes.<locals>.api_memories_timeseries  sE     ,	@)AA: B        D .55555' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLjwjj\hjjkkkCA????	@s"   4: 
C*AC*=A(C%%C*z$/v1/default/banks/{bank_id}/entitieszList entitieszqList all entities (people, organizations, etc.) known by the bank, ordered by mention count. Supports pagination.list_entitiesEntitiesz$Maximum number of entities to returnzOffset for paginationc                 ,  K   	 j         j                            | |||           d{V }t          d |d         D             |d         |d         |d                   S # t          $ r }t          |j        |j        	          d}~wt          t
          f$ r  t          $ rm}d
dl
}t          |           d|                                 }t                              d|  d|            t          dt          |          	          d}~ww xY w)z0List entities for a memory bank with pagination.)r   r   r  Nc                 &    g | ]}t          d i |S r+   )r   r{  r  s     r   r  z?_register_routes.<locals>.api_list_entities.<locals>.<listcomp>  s&    BBBq~****BBBr2   r   r   r   r   r   r  r   r  r  z/entities: rH   )rw  r  r  r   r@   r   r  r  r   r{  r  r   r  r  r  )	r$  r   r   r  r   r  r  r   r]  s	           r   api_list_entitiesz+_register_routes.<locals>.api_list_entities  sr     	@)77uV_ 8        D &BBDMBBB7m7mH~	    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLYwYY<YYZZZCA????	@s%   AA# #
D-BD&A(DDz*/v1/default/banks/{bank_id}/entities/graphzGet entity co-occurrence graphzVReturn a graph of entities (nodes) and their co-occurrences (edges) for visualization.get_entity_graphz/Maximum number of co-occurrence edges to returnr   z-Minimum cooccurrence_count to include an edge	min_countc                   K   	 j         j                            | |||           d{V S # t          $ r }t	          |j        |j                  d}~wt          t          f$ r  t          $ rm}ddl	}t          |           d|                                 }t                              d|  d|            t	          dt          |                    d}~ww xY w)	z-Return entity co-occurrence graph for a bank.)r   r  r  Nr  r   r  r  z/entities/graph: rH   )rw  r  r  r@   r   r  r  r   r{  r  r   r  r  r  )r$  r   r  r  r  r  r   r]  s          r   api_entity_graphz*_register_routes.<locals>.api_entity_graph  s3     	@)::u	? ;          ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL_w__Q]__```CA????	@s!   (. 
CAC1A(CCz0/v1/default/banks/{bank_id}/entities/{entity_id}zGet entity detailszOGet detailed information about an entity including observations (mental model).
get_entityr   c                   K   	 j         j                            | ||           d{V }|t          dd| d          t	          |d         |d         |d	         |d
         |d         t          |d                   d |d         D                       S # t          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}ddl}t          |           d|                                 }t                              d|  d| d|            t          dt          |                    d}~ww xY w)z%Get entity details with observations.rw  Nr.  zEntity z
 not foundr  r   r   r   r   r   r   c                 D    g | ]}t          |j        |j                   S rI  rJ  rK  s     r   r  z<_register_routes.<locals>.api_get_entity.<locals>.<listcomp>E  s:        .38#JZ[[[  r2   r   )r   r   r   r   r   r   r   r   r  r  z
/entities/r2  rH   )rw  r  r  r   r   r   r@   r  r  r   r{  r  r   r  r  r  )r$  r   r  r
  r  r  r   r]  s          r   api_get_entityz(_register_routes.<locals>.api_get_entity,  s     	@9+66w	[j6kkkkkkkkF~#<[i<[<[<[\\\\'$<%&67$_5!,/ -(
);<< %n5      ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLewee)eeWceefffCA????	@s%   BB 
E%C  EA+E		Ez;/v1/default/banks/{bank_id}/entities/{entity_id}/regeneratez+Regenerate entity observations (deprecated)zUThis endpoint is deprecated. Entity observations have been replaced by mental models.regenerate_entity_observationsT)r  r>  rJ   r)  ro   r  c                 (   K   t          dd          )z2Regenerate observations for an entity. DEPRECATED.i  zIThis endpoint is deprecated. Entity observations are no longer supported.r  r   )r$  r   r  s      r   "api_regenerate_entity_observationsz<_register_routes.<locals>.api_regenerate_entity_observationsU  s%       ^
 
 
 	
r2   z)/v1/default/banks/{bank_id}/mental-modelszList mental modelsz5List user-curated living documents that stay current.r  zMental ModelszFilter by tags)r  rJ   rh   zHow to match tagsrr   r6  zoDetail level: 'metadata' (names/tags only), 'content' (adds content/config), 'full' (includes reflect_response))r  r  )r  tags_filter)rh   allexactr  )r   r   r6  c           	        K   	 j         j                            | ||||||           d{V }t          d |D                       S # t          $ r }t          |j        |j                  d}~wt          t
          f$ r  t          $ rm}ddl
}	t          |           d|	                                 }
t                              d|  d	|
            t          d
t          |                    d}~ww xY w)zList mental models for a bank.)r$  ro   rp   r  r   r   r  Nc                 &    g | ]}t          d i |S r  )r?  r  s     r   r  zD_register_routes.<locals>.api_list_mental_models.<locals>.<listcomp>  s'    1b1b1bq2E2J2J2J2J1b1b1br2   r   r  r   r  Error in GET /v1/default/banks//mental-models: rH   )rw  r  r  rG  r@   r   r  r  r   r{  r  r   r  r  r  )r$  r  rp   r  r   r   r  rk  r  r  r   r]  s              r   api_list_mental_modelsz0_register_routes.<locals>.api_list_mental_modelsn  s^     *	@"%)"2"E"E % / #F # #      M +1b1bTa1b1b1bcccc' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLb7bbT`bbcccCA????	@%   AA 
C;A00C;A(C66C;z;/v1/default/banks/{bank_id}/mental-models/{mental_model_id}zGet mental modelz"Get a specific mental model by ID.get_mental_modelrV  c           	      d  K   	 j         j                            | |||           d{V }|t          dd| d          t	          di |S # t
          t          f$ r  t          $ r }t          |j        |j                  d}~wt          $ r#}t          dt          |                    d}~wt          $ rp}ddl}t          |           d	|                                 }t                              d
|  d| d|            t          dt          |                    d}~ww xY w)zGet a mental model by ID.)r$  rV  r  r  Nr.  Mental model 'r0  r  r'  r   r  r  /mental-models/r2  rH   r+   )rw  r  r  r   r?  r   r@   r  r  r{   r   r{  r  r  r  r  )	r$  rV  r  r  r  r  r  r   r]  s	           r   api_get_mental_modelz._register_routes.<locals>.api_get_mental_model  s     $	@!$!1!B!B / /	 "C " "      L ##<i_<i<i<ijjjj&66666#]3 	 	 	' 	L 	L 	LAM!(KKKK 	@ 	@ 	@CA???? 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLt7ttSbttfrttuuuCA????	@s1   AA D/,BD/B22D/?A+D**D/zC/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/historyzGet mental model historyzMGet the refresh history of a mental model, showing content changes over time.get_mental_model_historyc           	      N  K   	 j         j                            | ||           d{V }|t          dd| d          |S # t          t          f$ r  t
          $ r }t          |j        |j                  d}~wt          $ r#}t          dt          |                    d}~wt          $ rp}ddl}t          |           d	|                                 }t                              d
|  d| d|            t          dt          |                    d}~ww xY w)z*Get the refresh history of a mental model.r  Nr.  r  r0  r  r'  r   r  r  r  r8  rH   )rw  r  r  r   r   r@   r  r  r{   r   r{  r  r  r  r  )r$  rV  r  r   r  r  r   r]  s          r   api_get_mental_model_historyz6_register_routes.<locals>.api_get_mental_model_history  s     	@)BB / / C        D
 |#<i_<i<i<ijjjjK#]3 	 	 	' 	L 	L 	LAM!(KKKK 	@ 	@ 	@CA???? 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLs'ss/sseqss    CA????	@s1   A A D$!A<<D$	B''D$4A+DD$zCreate mental modelzCreate a mental model by running reflect with the source query in the background. Returns an operation ID to track progress. The content is auto-generated by the reflect endpoint. Use the operations endpoint to check completion status.r  r  r7  c                 N  K   	 j         j                            | |j        |j        d|j        r|j        nd|j        r|j        nd|j        |j        r|j        	                                nd|	  	         d{V }j         j        
                    | |d         |           d{V }t          |d         |d                   S # t          $ r#}t          dt          |          	          d}~wt          t          f$ r  t           $ r }t          |j        |j        	          d}~wt&          $ rm}d
dl}t          |           d|                                 }t,                              d|  d|            t          dt          |          	          d}~ww xY w)z5Create a mental model (async - returns operation_id).r  Nr  r   r  r)  )rV  r)  r'  r  r   r   Error in POST /v1/default/banks/r  rH   )rw  r  r  r[  r@  r   ro   rK   rB  r~  r  rU  r{   r   r   r   r@   r  r  r{  r  r  r  r  )	r$  r  r  r  r  r  r  r   r]  s	           r   api_create_mental_modelz1_register_routes.<locals>.api_create_mental_model  s     "	@!$!1!E!EY!./+/7 <"&)5TYY?59\K//111t / "F 
" 
" 
 
 
 
 
 
L 9+MM ,T 2 / N        F
 -\$=O^des^tuuuu 	@ 	@ 	@CA????#]3 	 	 	' 	L 	L 	LAM!(KKKK 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLcGccUaccdddCA????	@s1   CC	 	
F$C11F$D**F$7A(FF$zC/v1/default/banks/{bank_id}/mental-models/{mental_model_id}/refreshzRefresh mental modelzWSubmit an async task to re-run the source query through reflect and update the content.refresh_mental_modelc           	        K   	 j         j                            | ||           d{V }t          |d         d          S # t          $ r#}t          dt          |                    d}~wt          $ r#}t          dt          |                    d}~wt          t
          f$ r  t          $ r }t          |j
        |j                  d}~wt          $ rp}d	dl}t          |           d
|                                 }t                              d|  d| d|            t          dt          |                    d}~ww xY w)z>Refresh a mental model by re-running its source query (async).r  Nr)  r  r  r'  r  r.  r   r  r  r  z
/refresh: rH   )rw  r  r  r  r9   r   r   r{   r   r@   r  r  r{  r  r  r  r  )r$  rV  r  r  r  r  r   r]  s          r   api_refresh_mental_modelz2_register_routes.<locals>.api_refresh_mental_model  s     	@9+MM / / N        F
 0VN=S\deeee# 	@ 	@ 	@CA???? 	@ 	@ 	@CA????#]3 	 	 	' 	L 	L 	LAM!(KKKK 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLt7tt?ttfrtt    CA????	@s<   >A 
EA,,E9BE5CEA+EEzUpdate mental modelz1Update a mental model's name and/or source query.r  c           
      ~  K   	 j         j                            | ||j        |j        |j        |j        |j        r|j                                        nd|           d{V }|t          dd| d          t          di |S # t          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}ddl}t#          |           d|                                 }t&                              d	|  d
| d|            t          dt#          |                    d}~ww xY w)zUpdate a mental model.Nr  r.  r  r0  r  r   r  !Error in PATCH /v1/default/banks/r  r2  rH   r+   )rw  r  r  r[  r@  rK   ro   rB  r~  r   r?  r@   r  r  r   r{  r  r   r  r  r  )	r$  rV  r  r  r  r  r  r   r]  s	           r   api_update_mental_modelz1_register_routes.<locals>.api_update_mental_modelA  s      	@!$!1!E!E /Y!.?Y59\K//111t / "F 	" 	" 	 	 	 	 	 	L ##<i_<i<i<ijjjj&66666' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLvWvvUdvvhtvvwwwCA????	@s%   BB	 	
D<B..D<A+D77D<zDelete mental modelDelete a mental model.delete_mental_modelc           	      R  K   	 j         j                            | ||           d{V }|st          dd| d          ddiS # t          $ r }t          |j        |j                  d}~wt          $ r#}t          d	t          |                    d}~wt          t          f$ r  t          $ rp}d
dl}t          |           d|                                 }t                              d|  d| d|            t          dt          |                    d}~ww xY w)r  r  Nr.  r  r0  r  r  deletedr'  r   r  "Error in DELETE /v1/default/banks/r  r2  rH   )rw  r  r  r   r@   r  r  r{   r   r   r{  r  r  r  r  )r$  rV  r  r  r  r  r   r]  s          r   api_delete_mental_modelz1_register_routes.<locals>.api_delete_mental_modelj  s     	@I,@@ / / A        G
  k#<i_<i<i<ijjjji((' 	L 	L 	LAM!(KKKK 	@ 	@ 	@CA????#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLwgwwVewwiuwwxxxCA????	@s1   AA 
D&A--D&:BD&6A+D!!D&z&/v1/default/banks/{bank_id}/directiveszList directivesz/List hard rules that are injected into prompts.r  
DirectiveszOnly return active directivesr  c           	        K   	 j         j                            | ||||||           d{V }t          d |D                       S # t          $ r }t          |j        |j                  d}~wt          t
          f$ r  t          $ rm}ddl
}	t          |           d|	                                 }
t                              d|  d	|
            t          d
t          |                    d}~ww xY w)zList directives for a bank.)r$  ro   rp   r  r   r   r  Nc                 &    g | ]}t          d i |S r  )r&  r  s     r   r  zA_register_routes.<locals>.api_list_directives.<locals>.<listcomp>  s'    /[/[/[10A0F0FA0F0F/[/[/[r2   r  r  r   r  r  /directives: rH   )rw  r  r  r*  r@   r   r  r  r   r{  r  r   r  r  r  )r$  r  rp   r  r   r   r  rl  r  r  r   r]  s              r   api_list_directivesz-_register_routes.<locals>.api_list_directives  s^     $	@"y/?? %' /  @          J )/[/[PZ/[/[/[\\\\' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL_7__Q]__```CA????	@r  z5/v1/default/banks/{bank_id}/directives/{directive_id}zGet directivezGet a specific directive by ID.get_directiver  c           	        K   	 j         j                            | ||           d{V }|t          dd| d          t	          di |S # t
          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}ddl
}t          |           d|                                 }t                              d	|  d
| d|            t          dt          |                    d}~ww xY w)zGet a directive by ID.r$  r  r  Nr.  Directive 'r0  r  r   r  r  /directives/r2  rH   r+   )rw  r  r  r   r&  r@   r  r  r   r{  r  r   r  r  r  )r$  r  r  r  r  r  r   r]  s          r   api_get_directivez+_register_routes.<locals>.api_get_directive  sr     	@!i.<<) / =        I
  #<c,<c<c<cdddd$11y111' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLn7nnP\nn`lnnoooCA????	@s%   A
A 
DA55DA+C>>DzCreate directivez6Create a hard rule that will be injected into prompts.r  c           	      h  K   	 j         j                            | |j        |j        |j        |j        |j        |           d{V }t          d
i |S # t          $ r#}t          dt          |                    d}~wt          $ r }t          |j        |j                  d}~wt          t          f$ r  t           $ rm}ddl}t          |           d|                                 }t&                              d|  d|            t          d	t          |                    d}~ww xY w)zCreate a directive.r  Nr'  r  r   r  r  r  rH   r+   )rw  r  r  r[  r   r'  r(  ro   r&  r{   r   r   r@   r  r  r   r{  r  r  r  r  )r$  r  r  r  r  r  r   r]  s          r   api_create_directivez._register_routes.<locals>.api_create_directive  s     	@!i.??Y.Y / @        I %11y111 	@ 	@ 	@CA????' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL`G``R^``aaaCA????	@s1   AA 
D1 A>>D1B&&D1A(D,,D1zUpdate directivez Update a directive's properties.r  c           
      H  K   	 j         j                            | ||j        |j        |j        |j        |j        |           d{V }|t          dd| d          t          di |S # t          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}ddl}t!          |           d|                                 }t$                              d	|  d
| d|            t          dt!          |                    d}~ww xY w)zUpdate a directive.)r$  r  r[  r   r'  r(  ro   r  Nr.  r  r0  r  r   r  r  r  r2  rH   r+   )rw  r  r  r[  r   r'  r(  ro   r   r&  r@   r  r  r   r{  r  r   r  r  r  )	r$  r  r  r  r  r  r  r   r]  s	           r   api_update_directivez._register_routes.<locals>.api_update_directive  s      	@!i.??)Y.Y / @ 	 	 	 	 	 	 	 	I  #<c,<c<c<cdddd$11y111' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLpWppR^ppbnppqqqCA????	@s%   A(A. .
D!8BD!1A+DD!zDelete directiveDelete a directive.delete_directivec           	        K   	 j         j                            | ||           d{V }|st          dd| d          ddiS # t          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}d	dl	}t          |           d
|                                 }t                              d|  d| d|            t          dt          |                    d}~ww xY w)r  r  Nr.  r  r0  r  r  r  r   r  r  r  r2  rH   )rw  r  r  r   r@   r  r  r   r{  r  r   r  r  r  )r$  r  r  r  r  r  r   r]  s          r   api_delete_directivez._register_routes.<locals>.api_delete_directive,  sl     	@I,==) / >        G
  e#<c,<c<c<cddddi((' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLqgqqS_qqcoqqrrrCA????	@s%   AA 
C;A--C;A+C66C;z%/v1/default/banks/{bank_id}/documentszList documentsz{List documents with pagination and optional search. Documents are the source content from which memory units are extracted.list_documents	DocumentszVCase-insensitive substring filter on document ID (e.g. 'report' matches 'report-2024')zFilter documents by tags
any_strictz;How to match tags: 'any', 'all', 'any_strict', 'all_strict'c           	        K   	 j         j                            | ||||||           d{V }|S # t          $ r }t	          |j        |j                  d}~wt          t          f$ r  t          $ rm}ddl	}	t          |           d|	                                 }
t                              d|  d|
            t	          dt          |                    d}~ww xY w)	a  
        List documents for a memory bank with optional search.

        Args:
            bank_id: Memory Bank ID (from path)
            q: Case-insensitive substring filter on document ID
            tags: Filter documents by tags
            tags_match: How to match tags (any, all, any_strict, all_strict)
            limit: Maximum number of results (default: 100)
            offset: Offset for pagination (default: 0)
        )r$  r&  ro   rp   r   r   r  Nr  r   r  r  z/documents: rH   )rw  r  r  r@   r   r  r  r   r{  r  r   r  r  r  )r$  r  ro   rp   r   r   r  r   r  r  r   r]  s              r   api_list_documentsz,_register_routes.<locals>.api_list_documentsN  sA     @	@)88% / 9        D K' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLZwZZLZZ[[[CA????	@s!   -3 
C#AC#6A(CC#z?/v1/default/banks/{bank_id}/documents/{document_id:path}/chunkszList document chunksz=List all chunks for a given document, ordered by chunk index.list_document_chunksz"Maximum number of chunks to returnr  )r*   r  rJ   c           	        K   	 	j         j                            | ||||           d{V }|t          dd          |S # t          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}ddl	}t          |           d|                                 }t                              d|  d	| d
|            t          dt          |                    d}~ww xY w)a5  
        List all chunks for a document, ordered by chunk_index.

        Args:
            bank_id: Memory Bank ID (from path)
            document_id: Document ID (from path)
            limit: Maximum number of chunks to return (default: 100)
            offset: Offset for pagination (default: 0)
        )r$  r   r   r   r  Nr.  Document not foundr  r   r  r  /documents/z	/chunks: rH   )rw  r  r  r   r@   r  r  r   r{  r  r   r  r  r  )
r$  r   r   r   r  r  r  r  r   r]  s
            r   api_list_document_chunksz2_register_routes.<locals>.api_list_document_chunks  s]     0	@9+@@' / A        F ~#<PQQQQM' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLowoo;ooamoopppCA????	@s$   >A 
C7A))C7A+C22C7zB/v1/default/banks/{bank_id}/documents/{document_id:path}/reprocesszReprocess documenta  Re-run the retain pipeline on an existing document without changing its content. This deletes the existing memory units and re-extracts facts using the current engine configuration. Useful when the LLM model, chunking strategy, or extraction settings have changed.reprocess_documentc           	      (  K   	 j         j                            | ||           d{V }|t          dd          t	          d|d         |d         	          S # t
          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}d
dl
}t          |           d|                                 }t                              d|  d| d|            t          dt          |                    d}~ww xY w)z
        Reprocess a document by re-running retain with its existing content and parameters.

        Args:
            bank_id: Memory Bank ID (from path)
            document_id: Document ID (from path)
        )r$  r   r  Nr.  r  r  Tr)  r%  )r#  r)  r%  r   r  r  r  z/reprocess: rH   )rw  r  r  r   r  r@   r  r  r   r{  r  r   r  r  r  r$  r   r  r  r  r  r   r]  s          r   api_reprocess_documentz0_register_routes.<locals>.api_reprocess_document  s}     .	@9+>>' / ?        F
 ~#<PQQQQ,#N3"=1   
 ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLrwrr;rrdprrsssCA????	@s%   AA 
D(BD!A+DDz8/v1/default/banks/{bank_id}/documents/{document_id:path}zGet document detailsz3Get a specific document including its original textget_documentc           	        K   	 j         j                            || |           d{V }|st          dd          |S # t          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}ddl	}t          |           d|                                 }t                              d|  d	| d
|            t          dt          |                    d}~ww xY w)z
        Get a specific document with its original text.

        Args:
            bank_id: Memory Bank ID (from path)
            document_id: Document ID (from path)
        rw  Nr.  r  r  r   r  r  r  r2  rH   )rw  r  r  r   r@   r  r  r   r{  r  r   r  r  r  )r$  r   r  documentr  r  r   r]  s          r   api_get_documentz*_register_routes.<locals>.api_get_document  sD     $	@ Y-::;ap:qqqqqqqqH R#<PQQQQO' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLhwhh;hhZfhhiiiCA????	@s$   <A 
C5A''C5A+C00C5z /v1/default/banks/{bank_id}/tagsz	List tagszList all unique tags in a memory bank with usage counts. Supports wildcard search using '*' (e.g., 'user:*', '*-fred', 'tag*-2'). Case-insensitive. Use `source=mental_models` to list tags used on mental models instead of memories.	list_tagszWildcard pattern to filter tags (e.g., 'user:*' for user:alice, '*-admin' for role-admin). Use '*' as wildcard. Case-insensitive.rj  zOWhere to read tags from: 'memories' (memory_units, default) or 'mental_models'.z Maximum number of tags to returnr   )rj  rk  c                 *  K   	 |dk    r+
j         j                            | ||||           d{V }n*
j         j                            | ||||           d{V }|S # t          $ r }t          |j        |j                  d}~wt          t
          f$ r  t          $ rm}ddl
}t          |           d|                                 }	t                              d|  d|	            t          d	t          |                    d}~ww xY w)
u  
        List all unique tags in a memory bank.

        Use this endpoint to discover available tags or expand wildcard patterns.
        Supports '*' wildcards for flexible matching (case-insensitive):
        - 'user:*' matches user:alice, user:bob
        - '*-admin' matches role-admin, super-admin
        - 'env*-prod' matches env-prod, environment-prod

        Args:
            bank_id: Memory Bank ID (from path)
            q: Wildcard pattern to filter tags (use '*' as wildcard)
            source: Tag source — 'memories' (memory_units, default) or 'mental_models'
            limit: Maximum number of tags to return (default: 100)
            offset: Offset for pagination (default: 0)
        rk  )r$  patternr   r   r  Nr  r   r  r  z/tags: rH   )rw  r  list_mental_model_tagsr  r@   r   r  r  r   r{  r  r   r  r  r  )r$  r  r   r   r   r  r   r  r  r   r]  s             r   api_list_tagsz'_register_routes.<locals>.api_list_tags  s     R	@(( Y-DD#!$3 E         !Y-77#!$3 8         K' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLUwUU|UUVVVCA????	@s%   AA" "
D,BD%A(DDz"/v1/default/chunks/{chunk_id:path}zGet chunk detailszGet a specific chunk by its ID	get_chunkc                   K   	 j         j                            | |           d{V }|st          dd          |S # t          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rm}ddl	}t          |           d|                                 }t                              d|  d	|            t          d
t          |                    d}~ww xY w)z
        Get a specific chunk with its text.

        Args:
            chunk_id: Chunk ID (from path, format: bank_id_document_id_chunk_index)
        rw  Nr.  zChunk not foundr  r   r  zError in /v1/default/chunks/r2  rH   )rw  r  r  r   r@   r  r  r   r{  r  r   r  r  r  )r   r  chunkr  r  r   r]  s         r   api_get_chunkz'_register_routes.<locals>.api_get_chunkI  s8     	@)*44X4________E O#<MNNNNL' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLRRRLRRSSSCA????	@s$   ;A 
C1A&&C1A(C,,C1zUpdate documental  Update mutable fields on a document without re-processing its content.

**Tags** (`tags`): Propagated to all associated memory units. Observations derived from those units are invalidated and queued for re-consolidation under the new tags. Co-source memories from other documents that shared those observations are also reset.

At least one field must be provided.update_documentc           	      H  K   |j         t          dd          	 j        j                            || |j         |           d{V }|st          dd          t          d	          S # t          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}d
dl}t          |           d|                                 }t                              d|  d| d|            t          dt          |                    d}~ww xY w)a  
        Update mutable fields on a document without re-processing its content.

        Args:
            bank_id: Memory Bank ID (from path)
            document_id: Document ID (from path)
            body: Fields to update (tags, metadata, context)
        N  z*At least one field (tags) must be providedr  )ro   r  r.  r  Tr#  r   r  r  r  r2  rH   )ro   r   rw  r  r  r  r@   r  r  r   r{  r  r   r  r  r  )	r$  r   r  r  r  r  r  r   r]  s	           r   api_update_documentz-_register_routes.<locals>.api_update_documenth  s     6 9C8deeee	@9+;;Y /	 <        F  R#<PQQQQ)$7777' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLnWnnQ\nn`lnnoooCA????	@s%   AA. .
D!8BD!1A+DD!zDelete a documenta  Delete a document and all its associated memory units and links.

This will cascade delete:
- The document itself
- All memory units extracted from this document
- All links (temporal, semantic, entity) associated with those memory units

This operation cannot be undone.delete_documentc           	      L  K   	 j         j                            || |           d{V }|d         dk    rt          dd          t	          dd	| d
|d          d||d                   S # t
          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rp}ddl
}t          |           d|                                 }t                              d|  d| d|            t          dt          |                    d}~ww xY w)z
        Delete a document and all its associated memory units and links.

        Args:
            bank_id: Memory Bank ID (from path)
            document_id: Document ID to delete (from path)
        rw  Ndocument_deletedr   r.  r  r  Tz
Document 'z' and r  z- associated memory units deleted successfullyr  r  r  r  r2  rH   )rw  r  r  r   r  r@   r  r  r   r{  r  r   r  r  r  r  s          r   api_delete_documentz-_register_routes.<locals>.api_delete_document  s     0	@9+;;Kbq;rrrrrrrrF()Q..#<PQQQQ) F[  F  F?U8V  F  F  F'%+,B%C	    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLhwhh;hhZfhhiiiCA????	@s%   A*A0 0
D#:BD#3A+DD#z&/v1/default/banks/{bank_id}/operationszList async operationszGet a list of async operations for a specific agent, with optional filtering by status and operation type. Results are sorted by most recent first.list_operations
OperationszFFilter by status: pending, processing, completed, failed, or cancelledzlFilter by operation type: retain, consolidation, refresh_mental_model, file_convert_retain, webhook_deliveryr  z&Maximum number of operations to returnzNumber of operations to skipFz,Exclude parent batch operations from resultsr  exclude_parentsc           	        K   	 j         j                            | ||||||           d{V }t          | |d         ||d |d         D                       S # t          $ r }t          |j        |j                  d}~wt          t
          f$ r  t          $ rm}ddl
}	t          |           d	|	                                 }
t                              d
|  d|
            t          dt          |                    d}~ww xY w)zOList async operations for a memory bank with optional filtering and pagination.)r  r  r   r   r  r  Nr   c                 &    g | ]}t          d i |S r  )r  )r{  ops     r   r  zA_register_routes.<locals>.api_list_operations.<locals>.<listcomp>  s'    SSS-3333SSSr2   r  r  r  r   r  r  z/operations: rH   )rw  r  r  r  r@   r   r  r  r   r{  r  r   r  r  r  )r$  r  r   r   r   r  r  r  r  r  r   r]  s              r   api_list_operationsz-_register_routes.<locals>.api_list_operations  sz     .	@9+;; / / <        F *WoSSf\>RSSS    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL[w[[\[[\\\CA????	@s%   AA 
D%B  DA(DDz5/v1/default/banks/{bank_id}/operations/{operation_id}zGet operation statuszGet the status of a specific async operation. Returns 'pending', 'completed', or 'failed'. Completed operations are removed from storage, so 'completed' means the operation finished successfully.get_operation_statuszOInclude the raw task payload (submission params) in the response. May be large.r)  include_payloadc           	      P  K   	 	 t          j        |           n"# t          $ r t          dd|           w xY wj        j                            | |||           d{V }t          di |S # t          $ r }t          |j	        |j
                  d}~wt          t          f$ r  t          $ rp}ddl}t          |           d|                                 }t                               d|  d	| d
|            t          dt          |                    d}~ww xY w)z%Get the status of an async operation.r'  Invalid operation_id format: r  )r  r  Nr   r  r  /operations/r2  rH   r+   )uuidUUIDr{   r   rw  r  r  r  r@   r  r  r   r{  r  r   r  r  r  )	r$  r)  r  r  r  r  r  r   r]  s	           r   api_get_operation_statusz2_register_routes.<locals>.api_get_operation_status  s     &	@l	,'''' l l l#<j\h<j<jkkkkl 9+@@Xg A        F +44V444' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLn7nnP\nn`lnnoooCA????	@s1    A2 :7A2 2
D%<BD%5A+D  D%z Cancel a pending async operationz>Cancel a pending async operation by removing it from the queuecancel_operationc           	        K   	 	 t          j        |           n"# t          $ r t          dd|           w xY wj        j                            | ||           d{V }t          di |S # t          $ r#}t          dt          |                    d}~wt          $ r }t          |j
        |j                  d}~wt          t          f$ r  t          $ rp}ddl}t          |           d|                                 }t                               d	|  d
| d|            t          dt          |                    d}~ww xY w)z!Cancel a pending async operation.r'  r  r  rw  Nr.  r   r  r  r  r2  rH   r+   )r  r  r{   r   rw  r  r  r  r   r@   r  r  r   r{  r  r  r  r  r$  r)  r  r  r  r  r   r]  s          r   api_cancel_operationz._register_routes.<locals>.api_cancel_operation%  s     	@l	,'''' l l l#<j\h<j<jkkkkl 9+<<Wlds<ttttttttF*44V444 	@ 	@ 	@CA????' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLjwjjLjj\hjjkkkCA????	@=    A1 :6A1 1
E;BE&CEA+E

Ez;/v1/default/banks/{bank_id}/operations/{operation_id}/retryzRetry a failed async operationzARe-queue a failed async operation so the worker picks it up againretry_operationc           	        K   	 	 t          j        |           n"# t          $ r t          dd|           w xY wj        j                            | ||           d{V }t          di |S # t          $ r#}t          dt          |                    d}~wt          $ r }t          |j
        |j                  d}~wt          t          f$ r  t          $ rp}ddl}t          |           d|                                 }t                               d	|  d
| d|            t          dt          |                    d}~ww xY w)zRetry a failed async operation.r'  r  r  rw  Nr.  r   r  r  r  z/retry: rH   r+   )r  r  r{   r   rw  r  r  r  r   r@   r  r  r   r{  r  r  r  r  r  s          r   api_retry_operationz-_register_routes.<locals>.api_retry_operationH  s     	@l	,'''' l l l#<j\h<j<jkkkkl 9+;;G\cr;ssssssssF)33F333 	@ 	@ 	@CA????' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLuGuuQ]uugsuuvvvCA????	@r
  z#/v1/default/banks/{bank_id}/profilezGet memory bank profilez]Get disposition traits and mission for a memory bank. Returns 404 if the bank does not exist.get_bank_profilec           	        K   	 j         j                            | |d           d{V }|t          dd|  d          t	          |d         d	          r|d                                         nt          |d                   }|                    d
          pd}t          | |d         t          di |||          S # t          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rm}ddl}t!          |           d|                                 }t$                              d|  d|            t          dt!          |                    d}~ww xY w)z0Get memory bank profile (disposition + mission).Fr  create_if_missingNr.  Bank 'r0  r  r  r~  r  r   r[  r$  r[  r  r  r  r   r  r  
/profile: rH   r+   )rw  r  r  r   rC  r~  r   r+  r  r  r@   r  r  r   r{  r  r   r  r  r  )	r$  r  profiledisposition_dictr  r  r  r   r]  s	           r   api_get_bank_profilez._register_routes.<locals>.api_get_bank_profilej  s     !	@
  I,==E >        G #<YW<Y<Y<YZZZZ 7=1<@@2&11333'-011 
 kk),,2G&V_-AA0@AA"    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLXwXX,XXYYYCA????	@s%   B>C 
E4C))E4A(E//E4zUpdate memory bank dispositionzBUpdate bank's disposition traits (skepticism, literalism, empathy)update_bank_dispositionc           	      <  K   	 	j         j                            | |j                                        |           d{V  	j         j                            | |           d{V }t          |d         d          r|d                                         nt          |d                   }|                    d          pd}t          | |d         t          di |||          S # t          $ r }t          |j        |j        	          d}~wt          t          f$ r  t           $ rm}d
dl}t%          |           d|                                 }t(                              d|  d|            t          dt%          |          	          d}~ww xY w)zUpdate bank disposition traits.rw  Nr  r~  r  r   r[  r  r  r   r  r  r  rH   r+   )rw  r  r  r  r~  r  rC  r   r+  r  r  r@   r   r  r  r   r{  r  r   r  r  r  )
r$  r6  r  r  r  r  r  r  r   r]  s
            r   api_update_bank_dispositionz5_register_routes.<locals>.api_update_bank_disposition  s     	@)"::,7799? ;         
  I,==gWf=ggggggggG 7=1<@@2&11333'-011 
 kk),,2G&V_-AA0@AA"    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLXwXX,XXYYYCA????	@s%   C%C+ +
F5DF.A(FFz&/v1/default/banks/{bank_id}/backgroundz-Add/merge memory bank background (deprecated)zRDeprecated: Use PUT /mission instead. This endpoint now updates the mission field.add_bank_backgroundc                   K   	 j         j                            | |j        |           d{V }|                    d          pd}t          ||          S # t          $ r }t          |j        |j	                  d}~wt          t          f$ r  t          $ rm}ddl}t          |           d|                                 }t                              d	|  d
|            t          dt          |                    d}~ww xY w)zDDeprecated: Add or merge bank background. Now updates mission field.rw  Nr  r   )r  r  r  r   r  r  z/background: rH   )rw  r  merge_bank_missionr   r+  r  r@   r   r  r  r   r{  r  r   r  r  r  )	r$  r6  r  r  r  r  r  r   r]  s	           r   api_add_bank_backgroundz1_register_routes.<locals>.api_add_bank_background  sX     	@9+>>/ ?        F jj++1rG%g'JJJJ' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL[w[[\[[\\\CA????	@s%   AA 
D
$A??D
A(DD
z/v1/default/banks/{bank_id}zCreate or update memory bankzrCreate a new agent or update existing agent with disposition and mission. Auto-fills missing fields with defaults.create_or_update_bankcreate_bankc           	        K   	 
j         j                            | |           d{V  |j        -
j         j                            | |j        |           d{V  |                                }|r,
j         j        j                            | ||           d{V  
j         j                            | |           d{V }t          |d         d          r|d         	                                nt          |d                   }|                    d          pd}t          | |d         t          di |||	          S # t          $ r }t          |j        |j        
          d}~wt$          t          f$ r  t&          $ rm}ddl}t+          |           d|                                 }	t.                              d|  d|	            t          dt+          |          
          d}~ww xY w)z7Create or update an agent with disposition and mission.rw  Nr[  r  r  r~  r  r   r[  r  r  r   r  r  r2  rH   r+   rw  r  r  r[  update_bankr  r  r  rC  r~  r   r+  r  r  r@   r   r  r  r   r{  r  r   r  r  r  r$  r6  r  r  final_profiler  r  r  r  r   r]  s             r   api_create_or_update_bankz3_register_routes.<locals>.api_create_or_update_bank  s     )	@)"33G_3]]]]]]]]] |'i&22 $3 3          %7799N ui&7JJ7Tbdsttttttttt #&)"2"C"CG]l"C"m"mmmmmmmM =7FF8m,77999-677 
 $''	228bG&"6*-AA0@AA"    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLPwPP,PPQQQCA????	@%   EE	 	
G9E..G9A(G44G9zPartial update memory bankzJPartially update an agent's profile. Only provided fields will be updated.r$  c           	        K   	 
j         j                            | |           d{V  |j        -
j         j                            | |j        |           d{V  |                                }|r,
j         j        j                            | ||           d{V  
j         j                            | |           d{V }t          |d         d          r|d         	                                nt          |d                   }|                    d          pd}t          | |d         t          di |||	          S # t          $ r }t          |j        |j        
          d}~wt$          t          f$ r  t&          $ rm}ddl}t+          |           d|                                 }	t.                              d|  d|	            t          dt+          |          
          d}~ww xY w)zAPartially update an agent's profile (name, mission, disposition).rw  Nr"  r  r~  r  r   r[  r  r  r   r  r  r2  rH   r+   r#  r%  s             r   api_update_bankz)_register_routes.<locals>.api_update_bank  s     )	@)"33G_3]]]]]]]]] |'i&22 $3 3          %7799N ui&7JJ7Tbdsttttttttt #&)"2"C"CG]l"C"m"mmmmmmmM =7FF8m,77999-677 
 $''	228bG&"6*-AA0@AA"    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLVWVVVVWWWCA????	@r(  zDelete memory bankzDelete an entire memory bank including all memories, entities, documents, and the bank profile itself. This is a destructive operation that cannot be undone.delete_bankc           	      n  K   	 j         j                            | |           d{V }t          dd|  d|                    dd          |                    dd          z   |                    d	d          z   
          S # t
          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rm}ddl}t          |           d|                                 }t                              d|  d|            t          dt          |                    d}~ww xY w)z.Delete an entire memory bank and all its data.rw  NTr  z.' and all associated data deleted successfullyr  r   entities_deleteddocuments_deletedr  r  r  r  r2  rH   )rw  r  r+  r  r+  r@   r   r  r  r   r{  r  r   r  r  r  r$  r  r  r  r  r   r]  s         r   api_delete_bankz)_register_routes.<locals>.api_delete_bankS  s     	@9+77Q`7aaaaaaaaF!XXXX$jj)?CC**/334**0!445    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLWgWWWWXXXCA????	@s%   A>B 
D4B))D4A(D//D4z"/v1/default/banks/{bank_id}/importzImport bank templateur  Import a bank template manifest to create or update a bank's configuration, mental models, and directives. If the bank does not exist it is created. Config fields are applied as per-bank overrides. Mental models are matched by id, directives by name — existing ones are updated, new ones are created. Use dry_run=true to validate the manifest without applying changes.import_bank_templatezBank Templatesz#Validate only, do not apply changesr  c                 d  K   	 |                                  d{V }ddlm} 	 t                              |          }nR# |$ rJ}d |                                D             }t          ddd                    |                     d}~ww xY wt          |          }	|	r't          dd	d                    |	                     |r=t          | |j
        dud
 |j        pg D             d |j        pg D             d          S j        j                            | |           d{V  t!          j        j        | ||           d{V S # t"          $ r#}t          dt%          |                    d}~wt&          $ r }t          |j        |j                  d}~wt,          t          f$ r  t.          $ rm}ddl}
t%          |           d|
                                 }t4                              d|  d|            t          dt%          |                    d}~ww xY w)z Import a bank template manifest.Nr   )r  c                 n    g | ]2}d                      d |d         D                        d|d          3S ).c              3   4   K   | ]}t          |          V  d S ry  )r   )r{  locs     r   	<genexpr>zP_register_routes.<locals>.api_import_bank_template.<locals>.<listcomp>.<genexpr>  s(      %E%E3c#hh%E%E%E%E%E%Er2   r6  r2  msg)r  )r{  errs     r   r  zF_register_routes.<locals>.api_import_bank_template.<locals>.<listcomp>  sJ    lllZ]SXX%E%E#e*%E%E%EEEUUUUUlllr2   r'  z#Template schema validation failed: z; r  zTemplate validation failed: c                     g | ]	}|j         
S r+   r  r  s     r   r  zF_register_routes.<locals>.api_import_bank_template.<locals>.<listcomp>  s    *T*T*TA14*T*T*Tr2   c                     g | ]	}|j         
S r+   r  r  s     r   r  zF_register_routes.<locals>.api_import_bank_template.<locals>.<listcomp>  s    'P'P'P1'P'P'Pr2   T)r$  r  r  r  r  rw  )r  r$  r  r  r  r  z	/import: rH   )r   pydanticr  r  model_validater  r   r  r  r  r  rk  rl  rw  r  r  r  r{   r   r@   r  r  r   r{  r  r  r  r  )r$  r6  r  r  raw_bodyr  r  r  r  validation_errorsr  r   r]  s               r   api_import_bank_templatez2_register_routes.<locals>.api_import_bank_templatew  s     &3	@ %\\^^++++++H000000+::8DD"   llabaiaiakaklll# #T6ARARTT    !7t < <  # #X$))DU:V:VXX     1##'9D#8*T*T$:L:RPR*T*T*T'P'P9NB'P'P'P     )"33G_3]]]]]]]]]5y' /	           	@ 	@ 	@CA????' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL\G\\l\\]]]CA????	@s\    E A  E BABBA9E 
A	E 
H/E<<H/	F$$H/A(H**H/z"/v1/default/banks/{bank_id}/exportzExport bank templatezExport a bank's current configuration, mental models, and directives as a template manifest. The exported manifest can be imported into another bank to replicate the setup.export_bank_templatec                 D  K   	 j         j                            | |d           d{V }|t          dd|  d          j         j                            |           d{V  j         j        j                            |            d{V }t          t          j	        
                                          fd|                                D             }|rt          di |nd}j         j                            | |	           d{V }g }|D ]}|                    d
i           }	|	rt          di |	nt                      }
|                    t!          |d         |d         |d         |                    dg           |                    dd          |
                     j         j                            | d|           d{V }g }|D ]q}|                    t%          |d         |d         |                    dd          |                    dd          |                    dg                                rt'          t(          ||r|nd|r|nd          S # t*          $ r }t          |j        |j                  d}~wt0          t          f$ r  t2          $ rm}ddl}t7          |           d|                                 }t:                              d|  d|            t          dt7          |                    d}~ww xY w)z@Export a bank's config and mental models as a template manifest.Fr  Nr.  r  r0  r  c                 $    i | ]\  }}|v 	||S r+   r+   )r{  r|  rv   template_config_fieldss      r   r}  zF_register_routes.<locals>.api_export_bank_template.<locals>.<dictcomp>  s*    !i!i!i41aQRhMhMh!QMhMhMhr2   r  rB  r   r[  r@  ro   rK   rL  rM  r  r   r'  r   r(  T)r[  r   r'  r(  ro   r  r  r  z	/export: rH   r+   )rw  r  r  r   _authenticate_tenantr  _load_bank_configr  ra  r  r  r   r  r+  r5  r   r[  r  r  r  r  r@   r  r  r   r{  r  r   r  r  r  )r$  r  r  bank_overridesfiltered_overridesbank_configmental_models_rawtemplate_mental_modelsr  trigger_datarB  directives_rawtemplate_directivesr  r  r  r   rD  r]  s                    @r   api_export_bank_templatez2_register_routes.<locals>.api_export_bank_template  s#     D	@I,==E >        G #<YW<Y<Y<YZZZZ )"77HHHHHHHHH#&9#3#D#V#VW^#_#_______N &));)H)M)M)O)O%P%P"!i!i!i!i>3G3G3I3I!i!i!iFXb,BB/ABBB^bK '*i&6&I&I 'J ' ' ! ! ! ! ! ! EG"'  !vvi44@Lf,<<|<<<RdRfRf&--+d8Z%'%7VVFB//#%66,#=#= '  	 	 	 	 $'9#3#C#CUO $D $ $      N @B# 	 	#**)vY !)!"z1!5!5"#%%T":":UU62..      (5 8NX44TX2EO..4	    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL[7[[\[[\\\CA????	@s%   I(I/ /
L9JL2A(LLz/v1/bank-template-schemazGet bank template JSON SchemazxReturns the JSON Schema for the bank template manifest format. Use this to validate template manifests before importing.get_bank_template_schemac                  8   K   t                                           S )z6Return the JSON Schema for the bank template manifest.)r  model_json_schemar+   r2   r   api_get_bank_template_schemaz6_register_routes.<locals>.api_get_bank_template_schema  s       $55777r2   z(/v1/default/banks/{bank_id}/observationszClear all observationszcDelete all observations for a memory bank. This is useful for resetting the consolidated knowledge.clear_observationsc                 :  K   	 j         j                            | |           d{V }t          dd|                    dd           d|                    dd                    S # t
          $ r }t          |j        |j        	          d}~wt          t          f$ r  t          $ rm}ddl}t          |           d
|                                 }t                              d|  d|            t          dt          |          	          d}~ww xY w)z"Clear all observations for a bank.rw  NTzCleared r  r   z observationsr  r  r  r  /observations: rH   )rw  r  rT  r  r+  r@   r   r  r  r   r{  r  r   r  r  r  r/  s         r   api_clear_observationsz0_register_routes.<locals>.api_clear_observations  sa     	@9+>>wXg>hhhhhhhhF!P6::oq#A#APPP$jj!<<   
 ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLdgddVbddeeeCA????	@s%   A$A* *
D4BD-A(DDz1/v1/default/banks/{bank_id}/consolidation/recoverzRecover failed consolidationzReset all memories that were permanently marked as failed during consolidation (after exhausting all LLM retries and adaptive batch splitting) so they are picked up again on the next consolidation run. Does not delete any observations.recover_consolidationc                   K   	 j         j                            | |           d{V }t          |d                   S # t          $ r }t          |j        |j                  d}~wt          t
          f$ r  t          $ rm}ddl
}t          |           d|                                 }t                              d|  d	|            t          d
t          |                    d}~ww xY w)z1Reset consolidation-failed memories for recovery.rw  Nr  )r  r  r   r  r  z/consolidation/recover: rH   )rw  r  retry_failed_consolidationr  r@   r   r  r  r   r{  r  r   r  r  r  r/  s         r   api_recover_consolidationz3_register_routes.<locals>.api_recover_consolidation<  s.     	@9+FFw`oFppppppppF/f_>UVVVV' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLkGkk]ikklllCA????	@s$   <A 
C2A''C2A(C--C2z=/v1/default/banks/{bank_id}/memories/{memory_id}/observationszClear observations for a memoryzDelete all observations derived from a specific memory and reset it for re-consolidation. The memory itself is not deleted. A consolidation job is triggered automatically so the memory will produce fresh observations on the next consolidation run.clear_memory_observationsc           	        K   	 j         j                            | ||           d{V }t          |d                   S # t          $ r }t          |j        |j                  d}~wt          t
          f$ r  t          $ rp}ddl
}t          |           d|                                 }t                              d|  d	| d
|            t          dt          |                    d}~ww xY w)z6Clear all observations derived from a specific memory.r-  Nr  )r  r  r   r  r  r1  rV  rH   )rw  r  clear_observations_for_memoryr  r@   r   r  r  r   r{  r  r   r  r  r  )r$  r+  r  r  r  r  r   r]  s          r   api_clear_memory_observationsz7_register_routes.<locals>.api_clear_memory_observationsY  sW     "	@9+II# / J        F
 3AXYYYY' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLpWpp	ppbnpp    CA????	@s$   =A 
C6A((C6A+C11C6z"/v1/default/banks/{bank_id}/configzGet bank configurationu   Get fully resolved configuration for a bank including all hierarchical overrides (global → tenant → bank). The 'config' field contains all resolved config values. The 'overrides' field shows only bank-specific overrides.get_bank_configc                   K   t                      j        st          dd          	 	j        j                            |           d{V  	j        j        j        r[ddlm}  || d|          }	j        j        	                    	j        j        j        
                    |                     d{V  	j        j        j                            | |           d{V }	j        j        j                            |            d{V }t          | ||	          S # t          $ r }t          |j        |j                  d}~wt$          t          f$ r  t&          $ rm}ddl}t+          |           d
|                                 }t.                              d|  d|            t          dt+          |                    d}~ww xY w)zEGet configuration for a bank with all hierarchical overrides applied.r.  _Bank configuration API is disabled. Set HINDSIGHT_API_ENABLE_BANK_CONFIG_API=true to re-enable.r  Nr   )BankReadContextr`  r$  	operationr  r  r  r  	/config: rH   )r4   r	  r   rw  r  rE  _operation_validatorhindsight_api.extensionsrc  _validate_operationvalidate_bank_readr  r`  rF  r  r@   r  r  r   r{  r  r   r  r  r  )
r$  r  rc  r  config_dictrG  r  r  r   r]  s
            r   api_get_bank_configz-_register_routes.<locals>.api_get_bank_config~  sG      ||2 	x   	@)"77HHHHHHHHHy4 DDDDDD%ogARdsttti&::I$9LLSQQ        
 !$	 0 A Q QRY[j k kkkkkkkK $'9#3#D#V#VW^#_#_______N%gkUcdddd' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL[7[[\[[\\\CA????	@s%   C7D! !
G+EG$A(GGzUpdate bank configurationzUpdate configuration overrides for a bank. Only hierarchical fields can be overridden (LLM settings, retention parameters, etc.). Keys can be provided in Python field format (llm_provider) or environment variable format (HINDSIGHT_API_LLM_PROVIDER).r  c                 `  K   t                      j        st          dd          	 
j        j                            |           d{V  
j        j        j        r[ddlm}  || d|          }
j        j        	                    
j        j        j        
                    |                     d{V  
j        j        j                            | |j        |           d{V  
j        j        j                            | |           d{V }
j        j        j                            |            d{V }t!          | ||	          S # t"          $ r }t          |j        |j                  d}~wt(          $ r#}t          d
t+          |                    d}~wt,          t          f$ r  t.          $ rm}ddl}t+          |           d|                                 }	t4                              d|  d|	            t          dt+          |                    d}~ww xY w)z*Update configuration overrides for a bank.r.  rb  r  Nr   BankWriteContextr  rd  r  r'  r  r  rf  rH   )r4   r	  r   rw  r  rE  rg  rh  ro  ri  validate_bank_writer  r  r  r`  rF  r  r@   r  r  r{   r   r   r{  r  r  r  r  )r$  r6  r  ro  r  rk  rG  r  r  r   r]  s             r   api_update_bank_configz0_register_routes.<locals>.api_update_bank_config  s      ||2 	x   	@)"77HHHHHHHHHy4 EEEEEE&&wBVhwxxxi&::I$9MMcRR        
 )"3FFwPWP_apqqqqqqqqq !$	 0 A Q QRY[j k kkkkkkkK#&9#3#D#V#VW^#_#_______N%gkUcdddd' 	L 	L 	LAM!(KKKK 	@ 	@ 	@CA????#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL]W]]|]]^^^CA????	@s1   D(E 
H-E77H-F""H- A(H((H-zReset bank configurationzReset bank configuration to defaults by removing all bank-specific overrides. The bank will then use global and tenant-level configuration only.reset_bank_configc                   K   t                      j        st          dd          	 	j        j                            |           d{V  	j        j        j        r[ddlm}  || d|          }	j        j        	                    	j        j        j        
                    |                     d{V  	j        j        j                            |            d{V  	j        j        j                            | |           d{V }	j        j        j                            |            d{V }t          | ||	          S # t           $ r }t          |j        |j                  d}~wt&          t          f$ r  t(          $ rm}ddl}t-          |           d
|                                 }t0                              d|  d|            t          dt-          |                    d}~ww xY w)z<Reset bank configuration to defaults (remove all overrides).r.  rb  r  Nr   rn  rr  rd  r  r  r  rf  rH   )r4   r	  r   rw  r  rE  rg  rh  ro  ri  rp  r  rr  r`  rF  r  r@   r  r  r   r{  r  r   r  r  r  )
r$  r  ro  r  rk  rG  r  r  r   r]  s
            r   api_reset_bank_configz/_register_routes.<locals>.api_reset_bank_config  sw      ||2 	x   	@)"77HHHHHHHHHy4 EEEEEE&&wBUgvwwwi&::I$9MMcRR        
 )"3EEgNNNNNNNNN !$	 0 A Q QRY[j k kkkkkkkK#&9#3#D#V#VW^#_#_______N%gkUcdddd' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL^g^^P\^^___CA????	@s%   D!E 
G;E00G;A(G66G;z'/v1/default/banks/{bank_id}/consolidatezTrigger consolidationzLRun memory consolidation to create/update observations from recent memories.trigger_consolidationconsolidationc                   K   	 j         j                            | |           d{V }t          |d         |                    dd                    S # t
          $ r }t          |j        |j                  d}~wt          t          f$ r  t          $ rm}ddl}t          |           d	|                                 }t                              d
|  d|            t          dt          |                    d}~ww xY w)z)Trigger consolidation for a bank (async).r  Nr)  r  F)r)  r  r  r   r  r  z/consolidate: rH   )rw  r  submit_async_consolidationr  r+  r@   r   r  r  r   r{  r  r   r  r  r  r/  s         r   api_trigger_consolidationz3_register_routes.<locals>.api_trigger_consolidation  sJ     	@9+FFwhwFxxxxxxxxF(#N3#ZZ>>    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLaGaaS_aabbbCA????	@s%   AA 
D!A<<DA(DDz$/v1/default/banks/{bank_id}/webhookszRegister webhookzIRegister a webhook endpoint to receive event notifications for this bank.create_webhookWebhooks   )r  r>  rJ   r)  ro   r  c                   K   	 t          j                    }
j        j                            | ||j        |j        |j        |j        |j	        
                                |           d{V }|r|d         ng }t          |t                    rt          j        |          }|r|d         nd}t          |t                    rt          j        |          }t#          t          |d                   |d         |d         d|rt%          |          ng t'          |d                   |rt)          j        |          nt)                      t-          |d	         d
          r|d	                                         nt          |d	                   t-          |d         d
          r|d                                         nt          |d                   	  	        S # t0          t2          f$ r  t4          $ rm}ddl}t          |           d|                                 }	t:                              d|  d|	            t3          dt          |                    d}~ww xY w)zRegister a webhook for a bank.)r!  r  r  r  r  http_config_jsonr  Nr  r  r   r$  r  r  r  	isoformatr  	r   r$  r  r  r  r  r  r  r  r   r  r  /webhooks: rH   r  )r  uuid4rw  r  rz  r  r  r  r  r  model_dump_jsonr   r   r   r   r   dumpsr  r,   r   r  model_validate_jsonrC  r  r   r   r{  r  r  r  r  )r$  r6  r  r!  r(  event_types_valhttp_config_valr  r  r   r]  s             r   api_create_webhookz,_register_routes.<locals>.api_create_webhook.  s      ,	@J	(77%K~#/!(!4!D!D!F!F / 8 	 	 	 	 	 	 	 	C 58?c-00RO/3// >"&*_"="=47Ac-00TO/400 >"&*_"="="s4y>>IJ5DLD111"S^,,")-A/RRR&((3|,k::,3|,66888\*++3|,k::,3|,66888\*++   " $]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL^G^^P\^^___CA????	@s   GG I%8A(I  I%zList webhooksz(List all webhooks registered for a bank.list_webhooksc                   K   	 j         j                            | |           d{V }d t          fd|D                       S # t          t
          f$ r  t          $ rm}ddl}t          |           d|	                                 }t                              d|  d	|            t          d
t          |                    d}~ww xY w)zList webhooks for a bank.rw  Nc                    | d         }t          |t                    rt          j        |          }| d         }t          |t                    rt          j        |          }t          t          | d                   | d         | d         d |rt          |          ng t          | d                   |rt          j
        |          nt                      t          | d         d          r| d                                         nt          | d                   t          | d	         d          r| d	                                         nt          | d	                   
	  	        S )Nr  r  r   r$  r  r  r  r  r  r  )r   r   r   r   r   r  r  r,   r   r  r  rC  r  )r(  r  r  s      r   _parse_webhook_rowzG_register_routes.<locals>.api_list_webhooks.<locals>._parse_webhook_row  sO   "%m"4os33 B&*j&A&AO"%m"4ot44 B&*j&A&AO&3t9~~	NE
9H P_ 5 5 5b Y00&!- 1 Eo V V V*,,s<0+>> 0s<0::<<<S.//s<0+>> 0s<0::<<<S.//   r2   c                 &    g | ]} |          S r+   r+   )r{  r(  r  s     r   r  z?_register_routes.<locals>.api_list_webhooks.<locals>.<listcomp>  s%    -V-V-V#.@.@.E.E-V-V-Vr2   r  r   r  r  r  rH   r  )rw  r  r  r  r   r   r{  r  r   r  r  r  )r$  r  rowsr  r  r   r  r]  s         @r   api_list_webhooksz+_register_routes.<locals>.api_list_webhooksl  s3     '	@)77 / 8        D
  2 '-V-V-V-VQU-V-V-VWWWW#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL]7]]|]]^^^CA????	@s   AA C'A(CCz1/v1/default/banks/{bank_id}/webhooks/{webhook_id}zDelete webhookzRemove a registered webhook.delete_webhookr!  c           	        K   	 j         j                            | t          j        |          |           d{V }|st          dd          t          d          S # t          t
          f$ r  t          $ rp}ddl	}t          |           d	|                                 }t                              d
|  d| d|            t          dt          |                    d}~ww xY w)zDelete a webhook.rw  Nr.  Webhook not foundr  Tr  r   r  r  
/webhooks/r2  rH   )rw  r  r  r  r  r   r  r   r{  r  r   r  r  r  )r$  r!  r  r  r  r  r   r]  s          r   api_delete_webhookz,_register_routes.<locals>.api_delete_webhook  sA     	@I,;;	*%% / <        G
  Q#<OPPPP!$////#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLmgmmQ[mm_kmmnnnCA????	@s   AA" "C-=A+C((C-zUpdate webhookzTUpdate one or more fields of a registered webhook. Only provided fields are changed.update_webhookc                   K   	 g }t          j        |          | g}|j        }d|v r?|                    |j                   |                    dt          |                      d|v r?|                    |j                   |                    dt          |                      d|v r?|                    |j                   |                    dt          |                      d|v r?|                    |j                   |                    dt          |                      d	|v rR|                    |j	        
                                           |                    d
t          |           d           |st          dd          j        j                            | t          j        |          |||           d{V }|st          dd          |d         }t          |t                     rt#          j        |          }|d	         }	t          |	t&                    rt#          j        |	          }	t+          t!          |d                   |d         |d         d|rt-          |          ng t/          |d                   |	rt1          j        |	          nt1                      t5          |d         d          r|d                                         nt!          |d                   t5          |d         d          r|d                                         nt!          |d                   	  	        S # t8          t          f$ r  t:          $ rp}
ddl}t!          |
           d|                                 }t@          !                    d|  d| d|            t          dt!          |
                    d}
~
ww xY w)uM   Update a webhook's fields (PATCH semantics — only sent fields are updated).r  zurl = $r  z
secret = $r  zevent_types = $r  zenabled = $r  zhttp_config = $z::jsonbr  zNo fields provided to updater  )set_clausesparamsr  Nr.  r  r   r$  r  r  r  r  r   r  r  r  r2  rH   )"r  r  model_fields_setr   r  rO  r  r  r  r  r  r   rw  r  r  r   r   r   r   r   r  r  r,   r   r  r  rC  r  r   r{  r  r  r  r  )r$  r!  r6  r  r  r  fieldsr(  r  r  r  r  r   r]  s                r   api_update_webhookz,_register_routes.<locals>.api_update_webhook  s      A	@%'K Ij117;F-Fgk***""#:S[[#:#:;;;6!!gn---""#=F#=#=>>>&&g1222""#BS[[#B#BCCCF""go...""#>V#>#>???&&g1AACCDDD""#IS[[#I#I#IJJJ \#<Z[[[[	(77	*%%' / 8        C  Q#<OPPPP!-0O/3// >"&*_"="=!-0O/400 >"&*_"="="s4y>>IJ5DLD111"S^,,")-A/RRR&((3|,k::,3|,66888\*++3|,k::,3|,66888\*++   " $]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLlWllPZll^jllmmmCA????	@s   MM O(A+OOz</v1/default/banks/{bank_id}/webhooks/{webhook_id}/deliverieszList webhook deliveriesz>Inspect delivery history for a webhook (useful for debugging).list_webhook_deliveriesr  r  z&Maximum number of deliveries to return)r*   r  rJ   z+Pagination cursor (created_at of last item)cursorc           	      x  K   	 	 j         j                            | t          j        |          |||           d{V }n# t
          $ r t          dd          w xY wt          |          |k    }|d|         }|r|r|d         d         nd}t          d |D             |	          S # t          t          f$ r  t          $ rp}	d
dl}
t          |	           d|
                                 }t                              d|  d| d|            t          dt          |	                    d}	~	ww xY w)zUList deliveries for a specific webhook, newest first. Use next_cursor for pagination.)r   r  r  Nr.  r  r  rY   r  c                 \    g | ])}t                               t          |                    *S r+   )r   r/  r   )r{  r(  s     r   r  zI_register_routes.<locals>.api_list_webhook_deliveries.<locals>.<listcomp>6  s.    cccWZ.GGS		RRcccr2   )r   r2  r   r  r  r  z/deliveries: rH   )rw  r  r  r  r  LookupErrorr   rO  r1  r   r{  r  r   r  r  r  )r$  r!  r   r  r  r  has_morepager2  r  r  r   r]  s               r   api_list_webhook_deliveriesz5_register_routes.<locals>.api_list_webhook_deliveries  s      	@	Q Y-EEIj))!$3 F          Q Q Q#<OPPPPQ 4yy5(H<D4<OO$r(<004K.cc^bccc'    $]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLu7uujuugsuuvvvCA????	@s+   <A B. AAB. .D9	A+D44D9z$/v1/default/banks/{bank_id}/memorieszRetain memoriesa  Retain memory items with automatic fact extraction.

This is the main endpoint for storing memories. It supports both synchronous and asynchronous processing via the `async` parameter.

**Features:**
- Efficient batch processing
- Automatic fact extraction from natural language
- Entity recognition and linking
- Document tracking with automatic upsert (when document_id is provided)
- Temporal and semantic linking
- Optional asynchronous processing

**The system automatically:**
1. Extracts semantic facts from the content
2. Generates embeddings
3. Deduplicates similar facts
4. Creates temporal, semantic, and entity links
5. Tracks document metadata

**When `async=true`:** Returns immediately after queuing. Use the operations endpoint to monitor progress.

**When `async=false` (default):** Waits for processing to complete.

**Note:** If a memory item has a `document_id` that already exists, the old document and its memory units will be deleted before creating new ones (upsert behavior).retain_memoriesr  c                   K   t                      }	 i }|j        D ]}|j        }||vrg ||<   d|j        i}|j        dk    rd|d<   n|j        r
|j        |d<   |j        r
|j        |d<   |j        r
|j        |d<   |j        r
|j        |d<   |j        rd |j        D             |d	<   |j	        r
|j	        |d
<   |j
        
|j
        |d<   |j        
|j        |d<   ||                             |           |j        rg }d}	|                                D ]Z\  }
}j        j                            | ||j        |
|           d{V }|                    |d                    |	|d         z  }	[t$                              d| |	d|r|d         ndt)          |          dk    r|ndd          S ddlm}  |            }|j        rt1          dd          d}	t3          ddd          }|                    d| d          5  |                                D ]\  }
}j        j                            | ||j        |
|dj        j                            | |dt;          j                                         d{V \  }}|	t)          |          z  }	|r9t3          |j        |j        z   |j         |j         z   |j!        |j!        z             }	 ddd           n# 1 swxY w Y   t$                              d| |	d|d          S # tD          $ r }t1          |j#        |j$                  d}~wtJ          t0          f$ r  tL          $ r}ddl'}g }tQ          |j                  D ]a\  }}t)          |j                  d k    r|j        dd          d!z   n|j        }|                    d"| d#|d$|j         d%|j                    bd&)                    |          }tU          |           d't)          |j                   d(| d)|+                                 }tX          -                    d*|  d+|            t1          d,tU          |                    d}~ww xY w)-z/Retain memories with optional async processing.r   r   Nr  r   r   r   c                 0    g | ]}|j         |j        pd dS )r   r   r   r  s     r   r  z8_register_routes.<locals>.api_retain.<locals>.<listcomp>u  s+    /u/u/ubcI\S\0]0]/u/u/ur2   r]   ro   r   r   r   )r  r   r  r)  r%  Tr   )r#  r$  r%  r  r)  r*  r3   r'  aJ  Batch API is enabled (HINDSIGHT_API_RETAIN_BATCH_ENABLED=true) but async=false. Batch operations can take several minutes to hours and will timeout in synchronous mode. Please set async=true in your request to use background processing, or disable batch API by setting HINDSIGHT_API_RETAIN_BATCH_ENABLED=false in your environment.r  r  r  r<  )r$  r   )r$  contentsr)  rm  )r$  r  r  r   r  return_usageoutbox_callbackFr"  r   z...z  [z
] content=z
, context=z, timestamp=rP  z	

Input (z	 items):
r  r  z/memories (retain): rH   ).rC   r   r   r   r   r   r   r   r]   ro   r   r   r   r  rw  r  submit_async_retainr  r  r=  rO  ru  r4   retain_batch_enabledr   r<   rS  retain_batch_async_build_retain_outbox_callbackr6   r+  r  r   r!  r@   r  r  r   r{  r  r  r  r   r  r  r  )r$  r6  r  rW  strategy_groupsitem	effectivecontent_dictall_operation_idstotal_items_countgroup_strategyr  r  r4   r  total_usager&  r  r  input_summaryr  content_previewinput_debugr   r]  s                           r   
api_retainz$_register_routes.<locals>.api_retainB  sA     < ())~	@<>O @ @ M	O3313OI.&/%>>W,,15L..^ @15L.< ;.2lL+= =/3}L,# C262BL/= v/u/ugkgt/u/u/uL,9 5+/9L(*69=9PL!56#/262BL/	*11,????~ K$&!$%!0?0E0E0G0G 	? 	?,NH#&9#3#G#G &-&;!/(7 $H $ $      F &,,VN-CDDD%)>>%%%44#'#*'8!%@Q([(9!(<(<W[>ABS>T>TWX>X>X):):^b 	 	 	 <;;;;;#. 	'$'g    %&!(aqWXYYY--hPU-VV  4C4I4I4K4K  0.1i.>.Q.Q$+%-*1*?%3,;)-,/I,<,Z,Z(/)1-1'6':'<'<	 -[ - - /R / / ) ) ) ) ) ) *S]]:)  *4-8-EHZ-Z.9.G%J].]-8-EHZ-Z+ + +K#              0 &44#'#*'8!&!,    ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@ M$W]33  4@CDL@Q@QTW@W@W$,tt"4u"<"<]a]i$$n!nnnnDLnn^b^lnn    ))M22K q66 8 8gm,,8 88C8 8(33558 8 
 LLbwbbT`bbcccCA????%	@sQ   FL
 0AL
 CKL
 K##L
 &K#'"L
 

Q L//Q DQQ z(/v1/default/banks/{bank_id}/files/retainzConvert files to memoriesu  Upload files (PDF, DOCX, etc.), convert them to markdown, and retain as memories.

This endpoint handles file upload, conversion, and memory creation in a single operation.

**Features:**
- Supports PDF, DOCX, PPTX, XLSX, images (with OCR), audio (with transcription)
- Automatic file-to-markdown conversion using pluggable parsers
- Files stored in object storage (PostgreSQL by default, S3 for production)
- Each file becomes a separate document with optional metadata/tags
- Always processes asynchronously — returns operation IDs immediately

**The system automatically:**
1. Stores uploaded files in object storage
2. Converts files to markdown
3. Creates document records with file metadata
4. Extracts facts and creates memory units (same as regular retain)

Use the operations endpoint to monitor progress.

**Request format:** multipart/form-data with:
- `files`: One or more files to upload
- `request`: JSON string with FileRetainRequest model

**Parser selection:**
- Set `parser` in the request body to override the server default for all files.
- Set `parser` inside a `files_metadata` entry for per-file control.
- Pass a list (e.g. `['iris', 'markitdown']`) to define an ordered fallback chain — each parser is tried in sequence until one succeeds.
- Falls back to the server default (`HINDSIGHT_API_FILE_PARSER`) if not specified.
- Only parsers enabled on the server may be requested; others return HTTP 400.file_retainFiles.zFiles to upload and convertz(JSON string with FileRetainRequest modelfilesc           
        K   ddl m}  |            j        st          dd          	 	 t                              |          }n3# t          $ r&}t          ddt          |                     d}~ww xY wt          |          j	        k    rt          dd	j	         d
          |j
        r\t          |j
                  t          |          k    r7t          ddt          |j
                   dt          |           d          j        j        j                                        }j        j        n|dt          t           t                   z  dz  dt           t                   ffd}dt           t                   dt          ddffd}	|j         |	 ||j                  d           ddl}
g }d}t'          |          D ]\  }}|                                 d{V }|t          |          z  } G d d          } |||j        |j                  }|j
        r|j
        |         nt/                      }|j        pdt3          j                     }|j        |j        n|j        } ||          } |	|d|j         d           |||j        |j        pi |j        pg |j        ||j        d}|                     |           	|j!        k    r#|dz  }t          dd|ddj"         d          j        j        #                    | |d|            d{V }tH          %                    d!|d!         i          S # tL          $ r }t          |j'        |j(                  d}~wtR          t          f$ r  t          $ rm}ddl*}t          |           d"|+                                 }tX          -                    d#|  d$|            t          d%t          |                    d}~ww xY w)&z%Upload and convert files to memories.r   r3   r.  zUFile upload API is disabled. Set HINDSIGHT_API_ENABLE_FILE_UPLOAD_API=true to enable.r  r'  zInvalid request JSON: NzToo many files. Maximum z files per request.zfiles_metadata count (z) must match files count (rq  r-  r   c                 d    | j         S t          | t                    r| gnt          |           S )z4Normalize parser value to a non-empty list of names.)file_parserr   r   r,   )r-  r  s    r   _resolve_parserzB_register_routes.<locals>.api_file_retain.<locals>._resolve_parser0  s2    ;!-- *3 4 4Cuu$s))Cr2   parsersr   c           	      \    fd| D             }|rt          dd| d| d           dS )z:Raise HTTP 400 if any parser name is not in the allowlist.c                     g | ]}|v|	S r+   r+   )r{  p	allowlists     r   r  zX_register_routes.<locals>.api_file_retain.<locals>._validate_parsers.<locals>.<listcomp>8  s#    GGGAAY4F4Fa4F4F4Fr2   r'  zParser(s) not available (z): z. Available: r  Nr  )r  r   
disallowedr  s      r   _validate_parserszD_register_routes.<locals>.api_file_retain.<locals>._validate_parsers6  sd    GGGGGGG
 '$'k7kkzkk`ikk    r2   zrequest-level parserc                       e Zd Zd Zd ZdS )>_register_routes.<locals>.api_file_retain.<locals>.FileWrapperc                 0    || _         || _        || _        d S ry  )_contentfilenamer  )r   r   r  r  s       r   __init__zG_register_routes.<locals>.api_file_retain.<locals>.FileWrapper.__init__P  s    (/(0,8)))r2   c                    K   | j         S ry  )r  r   s    r   readzC_register_routes.<locals>.api_file_retain.<locals>.FileWrapper.readU  s      #},r2   N)rM   rN   rO   r  r  r+   r2   r   FileWrapperr  O  s2        9 9 9
- - - - -r2   r  file_zfile 'r  )filer   r   r   ro   r   r  r   i   zTotal batch size (z.1fzMB) exceeds maximum of MB)r$  
file_itemsr  r  r*  r  r  z/files/retain: rH   ).ru  r4   r
  r   r  r  r{  r   rO  file_conversion_max_batch_sizer  rw  r  _parser_registrylist_parsersfile_parser_allowlistr,   r  ior  r  r  r  r  r   r  r  r   r   ro   r   r   r   $file_conversion_max_batch_size_bytes!file_conversion_max_batch_size_mbsubmit_async_file_retainr,  r=  r@   r  r  r   r  r  r  r  )r$  r  r6  r  r4   request_datar  registered_parsersr  r  r  r  total_batch_sizer  r  file_contentr  wrapped_file	file_metadoc_id
raw_parserparser_chainr  total_mbr  r  r   r  r  r]  s                              @@r   api_file_retainz)_register_routes.<locals>.api_file_retain  s     N 	433333 , 	n   
y	@0DDWMM   # #<CFF<<    5zzFAAA# #pf6[ppp    * s<3N/O/OSVW\S]S]/]/]# #}C8S4T4T}}pstypzpz}}}    "%!1!B!O!O!Q!Q8>8T8`44fxIDS49_t%; DS	 D D D D D D49 s t       ".!!//,2E"F"FH^___ IIIJ $U++ %( %(4%)YY[[000000 C$5$55 - - - - - - - -  +{<HYZZ ?K>YsL7::_q_s_s	".H2H$*,,2H2H 2;1A1MY--S_Sf
.z::!!,0I0I0I0IJJJ )#)(0 ) 2 8b%N0b!*!4* ) 2	 	 !!$''''  &"MMM+{;# # B  B  B  BU[U}  B  B  B   
 9+DD%" /	 E        F &44#VO%<   ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLL]w]]|]]^^^CA????	@sC   A 
M 
A;!A66A;;KM 
P M;;PA(PPzClear memory bank memorieszDelete memory units for a memory bank. Optionally filter by type (world, experience, opinion) to delete only specific types. This is a destructive operation that cannot be undone. The bank profile (disposition and background) will be preserved.clear_bank_memoriesclear_memoriesz6Optional fact type filter (world, experience, opinion)c                   K   	 j         j                            | |d|           d{V  t          d          S # t          $ r }t          |j        |j                  d}~wt          t
          f$ r  t          $ rm}ddl
}t          |           d|                                 }t                              d	|  d
|            t          dt          |                    d}~ww xY w)z>Clear memories for a memory bank, optionally filtered by type.F)r%  delete_bank_profiler  NTr  r  r   r  r  z/memories: rH   )rw  r  r+  r  r@   r   r  r  r   r{  r  r   r  r  r  )r$  r   r  r  r  r   r]  s         r   api_clear_bank_memoriesz1_register_routes.<locals>.api_clear_bank_memories  sD     	@)"..4UTc /          "$////' 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@!!ffNNi6J6J6L6LNNLLLYwYY<YYZZZCA????	@s"   8> 
C.A##C.A(C))C.c                       e Zd ZU dZeed<   eed<   eed<   edz  ed<   edz  ed<   edz  ed<    edd	
          Zedz  ed<   e	ee
f         dz  ed<   e	ee
f         dz  ed<   e	ee
f         ed<   dS )'_register_routes.<locals>.AuditLogEntryzA single audit log entry.r   r9  r>  Nr$  r?  rE  u^   Server-computed duration in milliseconds (started_at → ended_at). Null if not yet completed.rI   rc  r6  rD  r   )rM   rN   rO   rP   r   rR   r#   rc  rQ   r   r   r+   r2   r   AuditLogEntryr    s         ''t$J*"'%x#
 #
 #
S4Z 	
 	
 	
 c3h$&&&&sCx.4''''sCx.     r2   r  c                   T    e Zd ZU dZeed<   eed<   eed<   eed<   e          ed<   dS )._register_routes.<locals>.AuditLogListResponsez,Response model for list audit logs endpoint.r$  r   r   r   r   N)rM   rN   rO   rP   r   rR   rQ   r,   )r  s   r   AuditLogListResponser    sN         ::





M""""""r2   r  c                   B    e Zd ZU dZeed<   eeef         ed<   eed<   dS )-_register_routes.<locals>.AuditLogStatsBucketz(A single time bucket in audit log stats.r  actionsr   N)rM   rN   rO   rP   r   rR   r   rQ   r+   r2   r   AuditLogStatsBucketr    s<         66			c3h




r2   r  c                   T    e Zd ZU dZeed<   eed<   eed<   eed<   e          ed<   dS )/_register_routes.<locals>.AuditLogStatsResponsez,Response model for audit log stats endpoint.r$  r!  r"  startr$  N)rM   rN   rO   rP   r   rR   r,   )r  s   r   AuditLogStatsResponser    sO         ::





)******r2   r  z&/v1/default/banks/{bank_id}/audit-logszList audit logsz@List audit log entries for a bank, ordered by most recent first.list_audit_logsAudit)r>  rJ   r)  ro   r  zFilter by action typez'Filter by transport (http, mcp, system)z)Filter from this ISO datetime (inclusive)z*Filter until this ISO datetime (exclusive)rH   zMax items to returnr  )r  rJ   r9  r>  
start_dateend_datec                 b  K   	 ddl m} j        j                                         d{V }	j        j                            | |d           d{V 	 t          dd|  d	          dd
lm}
  |
|	          4 d{V }dg}| g}d}|r2|	                    d|            |	                    |           |dz  }|r2|	                    d|            |	                    |           |dz  }|rZt          j        |                    dd                    }|	                    d|            |	                    |           |dz  }|rZt          j        |                    dd                    }|	                    d|            |	                    |           |dz  }d                    |          } |d          } |j        d| d| g|R   d{V }|r|d         nd}|	                    |           |	                    |            |j        d| d| d| d|dz    d	g|R   d{V }g }|D ]!}d}|d         }|d         }|r:|r8t!          |d           r(t#          ||z
                                  d!z            }nD|rB|r@	 t#          ||z
                                  d!z            }n# t&          t(          f$ r Y nw xY wd" }d# }|	                    t+          |d$                   |d%         |d&         |d'          ||           ||          | ||d(                    ||d)                    ||d*                   pi d+
           #| ||||d,cddd          d{V  S # 1 d{V swxY w Y   dS # t,          $ r }t          |j        |j        	          d}~wt2          t          f$ r  t4          $ rV}ddl}t8                              d-|                                            t          d.t+          |          	          d}~ww xY w)/z"List audit log entries for a bank.r   r8   NFr  r.  r  r0  r  acquire_with_retrybank_id = $1rx   
action = $r   ztransport = $r   r  zstarted_at >= $zstarted_at < $ AND 	audit_logzSELECT COUNT(*) as total FROM z WHERE r   z
                    SELECT id, action, transport, bank_id, started_at, ended_at,
                           request, response, metadata
                    FROM 
                    WHERE zI
                    ORDER BY started_at DESC
                    LIMIT $z	 OFFSET $z
                    r?  rE  total_secondsr   c                 p    | d S t          | d          r|                                 nt          |           S )Nr  )rC  r  r   vals    r   	_safe_isoz@_register_routes.<locals>.api_list_audit_logs.<locals>._safe_iso?  s7    ;#'429#{2K2KYs}}QTUXQYQYYr2   c                     | d S t          | t                    r| S t          | t                    rt          j        |           n| S ry  )r   r   r   r   r   r
  s    r   
_safe_jsonzA_register_routes.<locals>.api_list_audit_logs.<locals>._safe_jsonD  sD    ;#'4%c400 '#&J2<S#2F2FOtz#COr2   r   r9  r>  r$  r6  rD  r   )
r   r9  r>  r$  r?  rE  rc  r6  rD  r   )r$  r   r   r   r   zError listing audit logs: rH   )"hindsight_api.engine.memory_enginer8   rw  r  _get_backendr  r   hindsight_api.engine.db_utilsr  r   r   r  r   r  fetchrowfetchrC  rQ   r  r   AttributeErrorr   r@   r  r  r   r{  r  r  r  r  ) r$  r9  r>  r  r  r   r   r  r8   poolr  connwhere_clausesr  idxparsed_start
parsed_end	where_sqltable	count_rowr   r  r   r(  rc  startedendedr  r  r  r  r]  s                                   r   api_list_audit_logsz-_register_routes.<locals>.api_list_audit_logs  s     &{	@CCCCCC)6688888888D i&77_PU 8         
 $<YW<Y<Y<YZZZZHHHHHH))$// b b b b b b b4!/ 0%,I !(();c););<<<MM&)))1HC !(()>)>)>???MM),,,1HC #+#9*:L:LSRZ:[:[#\#\L!(()@3)@)@AAAMM,///1HC !)!78H8Hh8W8W!X!XJ!(()?#)?)?@@@MM*---1HC#LL77	 -- #0$-NUNN9NN## # #      	 /8>	'**Q e$$$f%%%'TZ    %	     +.'  
 
 
 
 
 
 
 
 
 
  % %C"&K!,/G
OE !5 !WWo-N-N !&)57?*I*I*K*Kd*R&S&S  !U !!*-uw.M.M.O.ORV.V*W*WKK )>: ! ! ! D!Z Z Z
P P P LL"%c$i..&)(m),[)9'*9~*3)G*<*<(1	%(8(8+6'1z#i.'A'A(2
3z?(C(C(2
3z?(C(C(Ir       '""$" yb b b b b b b b b b b b b b b b b b b b b b b b b b b b b bF ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@LLNi6J6J6L6LNNOOOCA????		@so   A?N HN'KNKNKBN/N 
NN NN 
P.N::P.AP))P.z,/v1/default/banks/{bank_id}/audit-logs/statszAudit log statisticsz9Get audit log counts grouped by time bucket for charting.audit_log_statszTime period: 1d, 7d, or 30dc           
      4  K   	 ddl m} ddlm} j        j                                         d{V }j        j                            | |d           d{V 	 t          dd|  d	
          ddl	m
} t          j        t          j                  }d}	|dk    r| |d          z
  }
n%|dk    r| |d          z
  }
n| |d          z
  }
 |d          } ||          4 d{V }ddg}| |
g}d}|r2|                    d|            |                    |           |dz  }d                    |          } |j        d|	 d| d| dg|R   d{V }i }|D ]<}|d                                         }||vri ||<   |d         ||         |d         <   =| ||	|
                                d  |                                D             d!cddd          d{V  S # 1 d{V swxY w Y   dS # t&          $ r }t          |j        |j        
          d}~wt,          t          f$ r  t.          $ rV}ddl}t2                              d"|                                            t          d#t9          |          
          d}~ww xY w)$z,Get audit log counts grouped by time bucket.r   r  r   NFr  r.  r  r0  r  )	timedeltaday1dr   )days30dr  r  r  r  zstarted_at >= $2r  r  r  z(
                    SELECT date_trunc('z', started_at) AS bucket,
                           action,
                           COUNT(*) AS count
                    FROM r  zi
                    GROUP BY bucket, action
                    ORDER BY bucket ASC
                    bucketr  r9  c                 ^    g | ]*\  }}||t          |                                          d +S ))r  r  r   )r  r  rz  s      r   r  zA_register_routes.<locals>.api_audit_log_stats.<locals>.<listcomp>  s7    pppX\XY[\q3qxxzz?? S Spppr2   )r$  r!  r"  r  r$  zError getting audit log stats: rH   )r  r  r  r8   rw  r  r  r  r   r   r#  rA  r   rB  r   r  r  r  r   r@   r  r  r   r{  r  r  r  r  r   )r$  r9  r!  r  r  r8   r  _tdrA  r"  r  r  r  r  r  r  r  r  r$  r(  
bucket_keyr  r  r]  s                          r   api_audit_log_statsz-_register_routes.<locals>.api_audit_log_statsk  sZ     K	@HHHHHHCCCCCC)6688888888D i&77_PU 8         
 $<YW<Y<Y<YZZZZ 211111,x|,,CE~~ccqkkk)5ccrlll*ccqkkk)H[))E))$// & & & & & & &4!/1C D%,e$4 !(();c););<<<MM&)))1HC#LL77	'TZ(-   	 
 %            68 F FC!$X!8!8!:!:J!00.0
+9<WGJ'H66  '$""__..pp`g`m`m`o`oppp A& & & & & & & & & & & & & & & & & & & & & & & & & & & & & &N ( 	L 	L 	LAM!(KKKK#]3 	 	 	 	@ 	@ 	@LLS9;O;O;Q;QSSTTTCA????		@sJ   C+G> 0C(G+G> +
G55G> 8G59G> >
JH##JAJJ)OrX  r   r   rE   exception_handlerr   r+  r  r  r   r   rQ   r,   r  postr   ra   rq  r8  r  r  r   r   r   r   rG  r   r?  rU  rI  r  patchrX  deleter*  r   r&  r,  r3  r  r  r  r  r  r  r  r  r  r  r  r  r  r  putr  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  r  r1  r  r  r,  r
   r   r   r!   )Jr]  rT  r  r  r  r  r  r!  r)  r5  r9  rf  rs  rx  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r	  r  r  r  r  r'  r*  r0  r@  rO  rS  rW  r[  r_  rl  rq  rt  ry  r  r  r  r  r  r  r  r  r  r  r   r,  r  r  sJ   `                                                                       @@r   r  r  0  s-    !!Q!Q!Q!QRRG8>t8L8L8L / /3: /Q_ / / / /& 	.//
9L 
 
 
 0/
 	WW'J^	   
E 
E 
E 
E 
E 	WW&3Q^"   
O 
 
 
 
2 	WW-G^	   N N N 	WW+('t Z     !&t&"&#*12E*F*F"@ "@"@Dj"@ "@ :	"@
 3i$"@ "@ 4Z"@ *"@ ("@ "@ "@ "@ "@ "@H 	WW3.# F$Z     *.*12E*F*F.@ .@.@Dj.@ :.@ !4Z	.@
 .@ .@ (.@ .@ .@ .@ .@ .@` 	WW:! b!Z    +22E*F*F@ @@@ (@ @ @ @ @ @8 	WWB)u.Z    +22E*F*F@ @@@ (@ @ @ @ @ @4 	XX5%g 'Z  
 
 WXPWXkPlPlk@ k@k@,k@?Mk@ k@ k@ k@ k@ 
 
k@Z 	XX-&-: Z    WYQXYlQmQms@ s@s@-s@@Ns@ s@ s@ s@ s@  s@j 	WW''B!Y    @GGZ?[?[ @ @n @ @ @ @ @ @ 	WW+(0O&Y    +22E*F*F+@ +@+@'+@ +@ +@ +@ +@ +@Z 	WW?1.e.Y     [
 
 
 +22E*F*F@ @@@ @ (@ @ @ @ @ @< 	WW.) H$\    34Z[[[A3JKKK*12E*F*F	@ @@@ @ (	@ @ @ @ @ @8 	WW4*0l'\    45fgggq6efff*12E*F*F	@ @@@ @ (	@ @ @ @ @ @, 	WW:+$e!\    IPPcHdHd@ @@!$@7E@ @ @ @ @ @B 	XXE+=k5\    +22E*F*F	
 	
	
	
 (	
 	
 	
 	
  	WW3.$K)    ).d&N^(_(_(_5:5Na5b5b5b9> J:
 :
 :
 31...A!nnn*12E*F*F!@ !@!@#Y%!@ 12!@ 56	!@ !@ !@ (!@ !@ !@ !@ !@ !@F 	WWE*"8'    :? J:
 :
 :
 +22E*F*F @  @ @ @ 56 @ ( @  @  @  @  @  @D 	WWM*c/    +22E*F*F@ @@@ (@ @ @ @ @ @< 	XX30%B +  	 	 W"&999 +22E*F*F%@ %@%@&%@ (%@ %@ %@ %@ %@ :9	 	%@N 	XXM3&m+    W#4888 +22E*F*F@ @@@ (@ @ @ @ @ 98 @< 	YYE*%G*    W"&999
 +22E*F*F	@ @@@ '@ (	@ @ @ @ @ :9 @@ 	ZZE%,*    W"$777 +22E*F*F@ @@@ (@ @ @ @ @ 87 @@ 	WW0,!E&^    ).d&N^(_(_(_5:5Na5b5b5b!$4STTT31...A!nnn*12E*F*F@ @@#Y%@ 12@ 	@
 @ @ (@ @ @ @ @ @@ 	WW?(5$^    +22E*F*F@ @@@ (@ @ @ @ @ @4 	XX0("L'^    Wv666 +22E*F*F@ @@$@ (@ @ @ @ @ 76 @< 	YY?("6'^    Wv666
 +22E*F*F	@ @@@ %@ (	@ @ @ @ @ 76 @@ 	ZZ?")'^    Wt444 +22E*F*F@ @@@ (@ @ @ @ @ 54 @4 	WW/,  R%]    v
 
 
 "'t9S!T!T!T&c
 
 
 *12E*F*F,@ ,@,@:,@
 3i$,@ ,@ ,@ ,@ (,@ ,@ ,@ ,@ ,@ ,@\ 	WWI)&S+]    31CghhhA!9PQQQ*12E*F*F$@ $@$@$@ $@ 	$@
 ($@ $@ $@ $@ $@ $@L 	XXL0$] *]  	 	 W!"" +22E*F*F"@ "@"@"@ ("@ "@ "@ "@ "@ #"	 	"@H 	WWB'&I#]    KRReJfJf@ @@#&@9G@ @ @ @ @ @4 	WW*'] !Z  	 	 5
 
 

 8=i8
 8
 8
 34VWWWA3JKKK*12E*F*F:@ :@:@::@ 34:@ :@ :@ (:@ :@ :@ :@ :@	 	:@x 	WW,$#4 ]    NUUhMiMi @ @c @N @ @ @ @ @ @. 	YYB-!/
 ']    Wf555
 +22E*F*F	#@ #@#@#@ $#@ (	#@ #@ #@ #@ #@ 65 #@J 	ZZB-#+ ']    Wd333JQReJfJf@ @@#&@9G@ @ @ @ @ 43 @B 	WW0-' j&^    #&n
 
 
 ! G
 
 
 2!AijjjA!9WXXX %eAo p p p*12E*F*F)@ )@)@d
)@
 Dj)@ )@ )@ )@ ()@ )@ )@ )@ )@ )@V 	WW?.&s+^    !&i!
 !
 !
 +22E*F*F@ @@@ @ (@ @ @ @ @ @@ 	ZZ?.2T'^    Wt444KRSfKgKg@ @@$'@:H@ @ @ @ @ 54 @4 	XXE-0W&^    Wd333KRSfKgKg@ @@$'@:H@ @ @ @ @ 43 @2 	WW-*)s'Y    T[[nSoSo #@ #@C #@. #@ #@ #@ #@ #@ #@J 	WW-*0X.Y    \ccv[w[w"@ "@"@7"@JX"@ "@ "@ "@ "@ "@H 	XX0)?h*Y    X__rWsWs@ @@3@FT@ @ @ @ @ @* 	WW%*. I,Y    W]T[\oTpTp-@ -@-@0-@CQ-@ -@ -@ -@ -@  -@^ 	YY%*,`"Y    W]T[\oTpTp-@ -@-@0-@CQ-@ -@ -@ -@ -@  -@^ 	ZZ%%$A"Y    W]$///NUViNjNj @ @s @^ @ @ @ @ @ 0/ @4 	XX,1&N ,  
 
 W#4888 e9^___*12E*F*F	:@ :@:@:@ :@ (	:@ :@ :@ :@ :@ 98
 
:@x 	WW,+&Z+    +22E*F*FI@ I@I@'I@ I@ I@ I@ I@ I@V 	WW"/D/   8 8 8 	ZZ2%(y)Y    W!666U\]pUqUq @ @c @N @ @ @ @ @ 76 @( 	XX;3._ -Y    W$D999X_`sXtXt @ @ @~ @ @ @ @ @ :9 @  	ZZG61I 1Z  	 	 W(=== +22E*F*F@ @@@ (@ @ @ @ @ >=	 	@4 	WW,)(|&Y    SZZmRnRn "@ "@3 "@ "@ "@ "@ "@ "@ "@H 	YY,)+B)Y    W!""SZ[nSoSo(@ (@(@/(@BP(@ (@ (@ (@ (@ #" (@T 	ZZ,)*M(Y    W 555T[\oTpTp #@ #@S #@> #@ #@ #@ #@ #@ 65 #@J 	XX1,'b,Y    W_D111X_`sXtXt @ @ @~ @ @ @ @ @ 21 @. 	XX.&"_%\    W +22E*F*F2@ 2@2@%2@ (2@ 2@ 2@ 2@ 2@  2@h 	WW.*>$\    +22E*F*F,@ ,@,@',@ ,@ ,@ ,@ ,@ ,@\ 	ZZ;% 2%\    WT222 +22E*F*F@ @@@ (@ @ @ @ @ 32 @0 	YY;& j%\    W
 +22E*F*F	H@ H@H@H@ &H@ (	H@ H@ H@ H@ H@  H@T 	WWF2)T.\    2#;cddd"4=jkkk*12E*F*F"@ "@"@"@ "@ d
	"@
 ("@ "@ "@ "@ "@ "@H 	XX.%!p$ 'Z/   2 WXPWXkPlPlD@ D@D@,D@?MD@ D@ D@ D@ D@ 3 4D@L 	XX2)+Y0 #Y;   > W]$/// #'s8U"V"V"VC-WXXX*12E*F*F	K@ K@K@JK@ K@ (	K@ K@ K@ K@ K@ 0/? @K@Z 	ZZ.%, K*Z    WT222 !3klll*12E*F*F@ @@Dj@ (@ @ @ @ @ 32 @2! ! ! ! !	 ! ! !"# # # # # # #y # # #    i   + + + + + + +	 + + + 	WW0!V&Y+    #45LMMM %d8a b b b!&t9d!e!e!e$T7cddd2!9NOOOA!1HIII*12E*F*FF@ F@F@d
F@ :F@ $J	F@
 *F@ F@ F@ (F@ F@ F@ F@ F@ F@P 	WW6&O&Y,    #45LMMMD.KLLL*12E*F*F	R@ R@R@d
R@ R@ (	R@ R@ R@ R@ R@ R@ R@ R@r2   )TN)rP   rs  r   ry  r]  r  
contextlibr   r   r   rV  r   r   fastapir   r	   r
   r   r   r   r   r   r   hindsight_api.engine.auditr   r   rh  r   r   r   r   r    r<  r!   r"   r#   r$   r%   r  r&   r1   ru  r4   r  r5   r6   r7   r8   'hindsight_api.engine.providers.none_llmr9   $hindsight_api.engine.response_modelsr:   r;   r<    hindsight_api.engine.search.tagsr=   r>   r?   r@   rA   hindsight_api.metricsrB   rC   rD   hindsight_api.modelsrE   	getLoggerrM   r  rG   rT   rW   r\   ra   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r,  r/  r1  r4  r8  rV  rZ  r]  r_  rf  ri  rn  rq  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r&  r*  r,  r3  r5  r?  rG  rI  rU  rX  r  r[  ra  r  r  r  r,   r  r  r  r  r  r  r  r  r  r  r  r  hindsight_api.webhooks.modelsr  r  r  r  r  r   r1  rX  r   r  r  r+   r2   r   <module>r<     sK       				  * * * * * * ' ' ' ' ' ' ' '         c c c c c c c c c c c c c c c c c c c c c c > > > > > > > > 8 8 8 8 8 8c d38n           S S S S S S S S S S S S S S & & & & & &Zh ZS Z Z Z Z> , + + + + + h h h h h h h h h h h h H H H H H H ` ` ` ` ` ` ` ` ` ` @ @ @ @ @ @ @ @ \ \ \ \ \ \ \ \ \ \ e e e e e e e e e e / / / / / /		8	$	$_ _ _ _ _9 _ _ _m m m m m) m m m    	       Y    > > > > >I > > >B% % % % %9 % % %P$ $ $ $ $	 $ $ $2 2 2 2 2) 2 2 2+ + + + +Y + + +.       8# # # # #) # # #L2 2 2 2 29 2 2 22s s s s s	 s s s3 3 3 3 3Y 3 3 3lr r r r r) r r rb\ b\ b\ b\ b\ b\ b\ b\J    I   @       (    	   6! ! ! ! !Y ! ! !H       (	 	 	 	 	) 	 	 	    i   
 
 
 
 
I 
 
 
O O O O OY O O Od$ $ $ $ $) $ $ $4: : : : :y : : :P P P P P P P P	j 	j 	j 	j 	ji 	j 	j 	jK K K K KY K K Kt t t t tY t t tm m m m m9 m m m4 4 4 4 4i 4 4 4nv v v v v	 v v v` ` ` ` `) ` ` `,# # # # #y # # #o o o o o	 o o o    i   
 
 
 
 
9 
 
 
1 1 1 1 1 1 1 1"
( 
( 
( 
( 
(9 
( 
( 
(    y   2f f f f f	 f f fR    y   ,u u u u u u u u6    	   B    i   :    I   >G G G G Gi G G G    y   0 l  l  l  l  ly  l  l  lF    I   $    Y       Y   (    I   0           	   	% 	% 	% 	% 	%Y 	% 	% 	%    i       9   -[ -[ -[ -[ -[	 -[ -[ -[`] ] ] ] ]Y ] ] ]       8" " " " "	 " " "# # # # #I # # #O O O O OY O O OI I I I IY I I II I I I I I I IX    )   <% % % % %i % % %g g g g gy g g g4T T T T T	 T T T] ] ] ] ]y ] ] ]6 !$     i   (UM UM UM UM UM UM UM UMpO O O O OI O O OY Y Y Y Y9 Y Y Yx_ _ _ _ _ _ _ _%; S	    @mm %m &	m
 "m m m m`' ' ' ' '	 ' ' 'Ti i i i iI i i i( ( ( ( (Y ( ( (<    i   $    Y   $% % % % %9 % % %/ / / / /i / / /d    9    _ _ _ _ _9 _ _ _H H H H Hi H H H6 < ; ; ; ; ;    9    " " " " "i " " "	k 	k 	k 	k 	k9 	k 	k 	k! ! ! ! !) ! ! !3
 3
 3
 3
 3
i 3
 3
 3
l# # # # #) # # #@HRt9K5K,L @ @ @ @J #+/y yyy "D(y 	y y y yx	U6@' U6@ U6@ U6@ U6@ U6@ U6@r2   