Save the current session under its stable agent identity. The worker owns * the live KV, so busy /save requests are deferred until a stable append-only * point and then executed by the worker thread. */
| 4339 | } |
| 4340 | if (text_len > UINT32_MAX) { |
| 4341 | snprintf(err, err_len, "rendered KV text key is too large"); |
| 4342 | free(text); |
| 4343 | return false; |
| 4344 | } |
| 4345 | const bool session_identity = session_title != NULL; |
| 4346 | uint64_t now = (uint64_t)time(NULL); |
| 4347 | uint64_t created_at = session_identity && session_created_at ? |
| 4348 | session_created_at : now; |
| 4349 | char sha[41]; |
| 4350 | if (session_identity) |
| 4351 | agent_session_identity_sha(session_title, created_at, sha); |
| 4352 | else |
| 4353 | ds4_kvstore_sha1_bytes_hex(text, text_len, sha); |
| 4354 | if (sha_out) memcpy(sha_out, sha, sizeof(sha)); |
| 4355 | |
| 4356 | ds4_session_payload_file staged = {0}; |
| 4357 | char save_err[160] = {0}; |
| 4358 | if (ds4_session_stage_payload(w->session, &staged, |
| 4359 | save_err, sizeof(save_err)) != 0) { |
| 4360 | snprintf(err, err_len, "%s", |
| 4361 | save_err[0] ? save_err : "session has no valid KV payload"); |
| 4362 | free(text); |
| 4363 | return false; |
| 4364 | } |
| 4365 | uint64_t payload_bytes = staged.bytes; |
| 4366 | |
| 4367 | agent_buf tmpl = {0}; |
| 4368 | agent_buf_puts(&tmpl, path); |
| 4369 | agent_buf_puts(&tmpl, ".tmp.XXXXXX"); |
| 4370 | char *tmp = agent_buf_take(&tmpl); |
| 4371 | int fd = mkstemp(tmp); |
| 4372 | if (fd < 0) { |
| 4373 | snprintf(err, err_len, "%s", strerror(errno)); |
| 4374 | ds4_session_payload_file_free(&staged); |
| 4375 | free(tmp); |
| 4376 | free(text); |
| 4377 | return false; |
| 4378 | } |
| 4379 | |
| 4380 | FILE *fp = fdopen(fd, "wb"); |
| 4381 | if (!fp) { |
| 4382 | snprintf(err, err_len, "%s", strerror(errno)); |
| 4383 | close(fd); |
| 4384 | unlink(tmp); |
| 4385 | ds4_session_payload_file_free(&staged); |
| 4386 | free(tmp); |
| 4387 | free(text); |
| 4388 | return false; |
| 4389 | } |
| 4390 | |
| 4391 | uint8_t h[DS4_KVSTORE_FIXED_HEADER]; |
| 4392 | ds4_kvstore_fill_header(h, (uint8_t)model_id, (uint8_t)quant_bits, |
| 4393 | ds4_kvstore_reason_code(reason), |
| 4394 | session_identity ? DS4_KVSTORE_EXT_SESSION_TITLE : 0, |
| 4395 | (uint32_t)tokens->len, 0, |
| 4396 | (uint32_t)ds4_session_ctx(w->session), |
| 4397 | created_at, now, payload_bytes); |
| 4398 | uint8_t tb[4]; |
no test coverage detected