Merge branch 'fix/g08' into fix/integrated

# Conflicts:
#	internal/store/migrations.go
This commit is contained in:
kami
2026-08-01 14:38:39 +04:00
39 changed files with 2753 additions and 363 deletions
+35 -14
View File
@@ -227,14 +227,16 @@ type IngestMailResp struct {
//
// Source is provenance recorded on the stored blob: "telegram", "web:upload".
//
// Exactly one of Data or ID is set. ID re-describes an image core already has —
// a different question, or the first attempt that succeeds after a vision model
// finally lands on disk.
// Exactly one of Data or ID is set, and core refuses a request carrying both:
// it used to take the ID branch and drop the bytes without a word.
//
// The method exists only when core has both a media store and an enabled vision
// block; otherwise it answers ErrUnknownMethod, which is what "off unless
// configured" looks like at the wire. A surface cannot make Maven look at
// pictures by merely sending one.
// The method exists when core has a media store. Vision being off does NOT
// remove it: the bytes are stored and the answer says she cannot read the
// picture yet, which is re-runnable by ID once a vision model is on disk, and
// it is the state this box is in today. So a surface that gets a reply with an
// id and an empty description has not failed, it has stored something. With no
// media block the method answers ErrUnknownMethod, which is what "off unless
// configured" looks like at the wire.
type DescribeImageReq struct {
Data []byte `json:"data,omitempty"`
ID string `json:"id,omitempty"`
@@ -243,6 +245,10 @@ type DescribeImageReq struct {
// SaveNote — also write the description as a note (source
// "media:image:<id-prefix>") so it is recallable later. Default false: a
// glance at a screenshot is not automatically a memory.
//
// Setting it raises what the call needs: an embedded note is recall corpus,
// so the caller's source scope must cover auth.ImageNoteSource. Describing
// without saving stays an ordinary read.
SaveNote bool `json:"save_note,omitempty"`
}
@@ -278,9 +284,14 @@ type CaptureStartReq struct {
// which it stops itself; the caller tells him, so a forgotten recording is his
// own informed choice rather than a surprise.
type CaptureStartResp struct {
Label string `json:"label,omitempty"`
Started time.Time `json:"started"`
MaxSeconds int `json:"max_seconds"`
Label string `json:"label,omitempty"`
Started time.Time `json:"started"`
// Token names THIS session. Every later append, stop and discard has to
// carry it. Without it the recorder is addressed by "whatever is running
// now", and a client whose session already ended on the duration cap goes on
// appending its microphone into the next session someone else started.
Token string `json:"token"`
MaxSeconds int `json:"max_seconds"`
}
// CaptureAppendReq — one chunk of audio for the running session. Refused with
@@ -288,6 +299,9 @@ type CaptureStartResp struct {
// makes an ambient path impossible: audio arriving at an idle core is dropped on
// the floor, not buffered "just in case".
type CaptureAppendReq struct {
// Token from CaptureStartResp. A frame for a session that already ended is
// refused rather than folded into whatever is running now.
Token string `json:"token"`
Audio audio.Audio `json:"audio"`
}
@@ -306,15 +320,22 @@ type CaptureAppendResp struct {
// flag rather than a separate method so the client that says "stop" and the
// client that says "stop and forget" take the same path to the same session.
type CaptureStopReq struct {
Discard bool `json:"discard,omitempty"`
// Token from CaptureStartResp. Stopping by "whatever is running" lets a
// late client end a recording it never started.
Token string `json:"token"`
Discard bool `json:"discard,omitempty"`
}
// CaptureStopResp — the finished capture. BlobID is the stored WAV, kept under
// media.retention like any other blob and pruned with it.
//
// A response with a Transcript and an empty Summary is a degraded success: the
// words exist, only the model failed. A response with a BlobID and neither is
// the audio surviving a transcription failure — the same id can be run again.
// A response with a Transcript and an empty Summary is the normal shape, not a
// failure: summarising a long meeting is a map-reduce of minutes, so stop
// answers with the words and the summary note is written afterwards. Summary is
// filled in only when it happened to be ready. A response with a BlobID and no
// transcript is the audio surviving a transcription failure — the same id can be
// run again by hand off the blob before media.retention prunes it — there is no
// capture method that takes a blob id, so this is not a re-run the wire offers.
// Discarded is true when nothing was kept.
type CaptureStopResp struct {
BlobID string `json:"blob_id,omitempty"`