runtime: remove worker transcript projection
This commit is contained in:
@@ -19,9 +19,10 @@ use worker_runtime::catalog::{
|
||||
WorkerStatus as EmbeddedWorkerStatus, WorkingDirectoryClaim, WorkingDirectoryRequest,
|
||||
WorkingDirectoryStatus, WorkingDirectorySummary,
|
||||
};
|
||||
use worker_runtime::config_bundle::{ConfigBundle, ConfigBundleAvailability, ConfigBundleSummary};
|
||||
#[cfg(test)]
|
||||
use worker_runtime::config_bundle::{
|
||||
ConfigBundle, ConfigBundleAvailability, ConfigBundleMetadata, ConfigBundleProvenance,
|
||||
ConfigBundleSummary, ConfigProfileDescriptor,
|
||||
ConfigBundleMetadata, ConfigBundleProvenance, ConfigProfileDescriptor,
|
||||
};
|
||||
use worker_runtime::error::RuntimeError as EmbeddedRuntimeError;
|
||||
use worker_runtime::execution::{
|
||||
@@ -30,10 +31,10 @@ use worker_runtime::execution::{
|
||||
use worker_runtime::fs_store::FsRuntimeStoreOptions;
|
||||
use worker_runtime::http_server::{
|
||||
RuntimeHttpConfigBundleAvailabilityResponse, RuntimeHttpConfigBundleSyncRequest,
|
||||
RuntimeHttpErrorResponse, RuntimeHttpSummaryResponse, RuntimeHttpTranscriptResponse,
|
||||
RuntimeHttpWorkerInputResponse, RuntimeHttpWorkerLifecycleRequest,
|
||||
RuntimeHttpWorkerLifecycleResponse, RuntimeHttpWorkerResponse, RuntimeHttpWorkersResponse,
|
||||
RuntimeHttpWorkingDirectoriesResponse, RuntimeHttpWorkingDirectoryResponse,
|
||||
RuntimeHttpErrorResponse, RuntimeHttpSummaryResponse, RuntimeHttpWorkerInputResponse,
|
||||
RuntimeHttpWorkerLifecycleRequest, RuntimeHttpWorkerLifecycleResponse,
|
||||
RuntimeHttpWorkerResponse, RuntimeHttpWorkersResponse, RuntimeHttpWorkingDirectoriesResponse,
|
||||
RuntimeHttpWorkingDirectoryResponse,
|
||||
};
|
||||
use worker_runtime::identity::{
|
||||
RuntimeId as EmbeddedRuntimeId, WorkerId as EmbeddedWorkerId, WorkerRef as EmbeddedWorkerRef,
|
||||
@@ -42,9 +43,6 @@ use worker_runtime::interaction::{
|
||||
WorkerInput as EmbeddedWorkerInput, WorkerInputKind as EmbeddedWorkerInputKind,
|
||||
};
|
||||
use worker_runtime::management::{RuntimeOptions as EmbeddedRuntimeOptions, RuntimeStatus};
|
||||
use worker_runtime::observation::{
|
||||
TranscriptProjection as EmbeddedTranscriptProjection, TranscriptQuery, TranscriptRole,
|
||||
};
|
||||
use worker_runtime::profile_archive::{ProfileSourceArchive, ProfileSourceArchiveInput};
|
||||
|
||||
const EMBEDDED_RUNTIME_ID: &str = "embedded-worker-runtime";
|
||||
@@ -454,34 +452,10 @@ pub struct WorkerInputResult {
|
||||
pub runtime_id: String,
|
||||
pub worker_id: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub transcript_sequence: Option<u64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub event_id: Option<u64>,
|
||||
pub diagnostics: Vec<RuntimeDiagnostic>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct WorkerTranscriptItem {
|
||||
pub sequence: u64,
|
||||
pub role: String,
|
||||
pub content: String,
|
||||
pub event_id: u64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct WorkerTranscriptProjection {
|
||||
pub state: WorkerOperationState,
|
||||
pub runtime_id: String,
|
||||
pub worker_id: String,
|
||||
pub start: usize,
|
||||
pub limit: usize,
|
||||
pub total_items: usize,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub next_start: Option<usize>,
|
||||
pub items: Vec<WorkerTranscriptItem>,
|
||||
pub diagnostics: Vec<RuntimeDiagnostic>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct WorkerProxyConnectPoint {
|
||||
pub kind: String,
|
||||
@@ -705,7 +679,6 @@ pub trait WorkspaceWorkerRuntime: Send + Sync {
|
||||
state: WorkerOperationState::Unsupported,
|
||||
runtime_id: self.runtime_id().to_string(),
|
||||
worker_id: worker_id.to_string(),
|
||||
transcript_sequence: None,
|
||||
event_id: None,
|
||||
diagnostics: vec![diagnostic(
|
||||
"worker_input_pending",
|
||||
@@ -717,31 +690,6 @@ pub trait WorkspaceWorkerRuntime: Send + Sync {
|
||||
}
|
||||
}
|
||||
|
||||
fn transcript(
|
||||
&self,
|
||||
worker_id: &str,
|
||||
start: usize,
|
||||
limit: usize,
|
||||
) -> WorkerTranscriptProjection {
|
||||
WorkerTranscriptProjection {
|
||||
state: WorkerOperationState::Unsupported,
|
||||
runtime_id: self.runtime_id().to_string(),
|
||||
worker_id: worker_id.to_string(),
|
||||
start,
|
||||
limit,
|
||||
total_items: 0,
|
||||
next_start: None,
|
||||
items: Vec::new(),
|
||||
diagnostics: vec![diagnostic(
|
||||
"worker_transcript_pending",
|
||||
DiagnosticSeverity::Info,
|
||||
format!(
|
||||
"bounded transcript for '{worker_id}' is not implemented by this registry source"
|
||||
),
|
||||
)],
|
||||
}
|
||||
}
|
||||
|
||||
fn proxy_connect_points(&self, worker_id: &str) -> Vec<WorkerProxyConnectPoint> {
|
||||
vec![WorkerProxyConnectPoint {
|
||||
kind: "stream_proxy".to_string(),
|
||||
@@ -1050,27 +998,6 @@ impl RuntimeRegistry {
|
||||
Ok(runtime.send_input(worker_id, request))
|
||||
}
|
||||
|
||||
pub fn transcript(
|
||||
&self,
|
||||
runtime_id: &str,
|
||||
worker_id: &str,
|
||||
start: usize,
|
||||
limit: usize,
|
||||
) -> Result<WorkerTranscriptProjection, RuntimeRegistryError> {
|
||||
validate_backend_identifier("runtime_id", runtime_id)?;
|
||||
validate_backend_identifier("worker_id", worker_id)?;
|
||||
let runtime = self.runtime(runtime_id)?;
|
||||
let lookup = runtime.worker(worker_id);
|
||||
if lookup.worker.is_none() {
|
||||
return Err(operation_failed_or_unknown_worker(
|
||||
runtime_id,
|
||||
worker_id,
|
||||
lookup.diagnostics,
|
||||
));
|
||||
}
|
||||
Ok(runtime.transcript(worker_id, start, limit))
|
||||
}
|
||||
|
||||
pub fn stop_worker(
|
||||
&self,
|
||||
runtime_id: &str,
|
||||
@@ -1781,7 +1708,6 @@ impl WorkspaceWorkerRuntime for EmbeddedWorkerRuntime {
|
||||
state: WorkerOperationState::Accepted,
|
||||
runtime_id: self.runtime_id.clone(),
|
||||
worker_id: worker_id.to_string(),
|
||||
transcript_sequence: Some(ack.transcript_sequence),
|
||||
event_id: Some(ack.event_id),
|
||||
diagnostics: Vec::new(),
|
||||
},
|
||||
@@ -1792,42 +1718,6 @@ impl WorkspaceWorkerRuntime for EmbeddedWorkerRuntime {
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
fn transcript(
|
||||
&self,
|
||||
worker_id: &str,
|
||||
start: usize,
|
||||
limit: usize,
|
||||
) -> WorkerTranscriptProjection {
|
||||
let Some(worker_ref) = self.worker_ref(worker_id) else {
|
||||
return embedded_transcript_rejected(
|
||||
&self.runtime_id,
|
||||
worker_id,
|
||||
start,
|
||||
limit,
|
||||
diagnostic(
|
||||
"embedded_worker_id_invalid",
|
||||
DiagnosticSeverity::Warning,
|
||||
"Worker id was empty and cannot be resolved".to_string(),
|
||||
),
|
||||
);
|
||||
};
|
||||
match self
|
||||
.runtime
|
||||
.transcript_projection(&worker_ref, TranscriptQuery::new(start, limit))
|
||||
{
|
||||
Ok(projection) => {
|
||||
embedded_transcript_projection(&self.runtime_id, worker_id, projection)
|
||||
}
|
||||
Err(err) => embedded_transcript_rejected(
|
||||
&self.runtime_id,
|
||||
worker_id,
|
||||
start,
|
||||
limit,
|
||||
embedded_runtime_diagnostic(&err),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -2444,31 +2334,12 @@ impl WorkspaceWorkerRuntime for RemoteWorkerRuntime {
|
||||
state: WorkerOperationState::Accepted,
|
||||
runtime_id: self.runtime_id.clone(),
|
||||
worker_id: worker_id.to_string(),
|
||||
transcript_sequence: Some(response.ack.transcript_sequence),
|
||||
event_id: Some(response.ack.event_id),
|
||||
diagnostics: Vec::new(),
|
||||
},
|
||||
Err(diagnostic) => remote_input_rejected(&self.runtime_id, worker_id, diagnostic),
|
||||
}
|
||||
}
|
||||
|
||||
fn transcript(
|
||||
&self,
|
||||
worker_id: &str,
|
||||
start: usize,
|
||||
limit: usize,
|
||||
) -> WorkerTranscriptProjection {
|
||||
match self.get_json::<RuntimeHttpTranscriptResponse>(&format!(
|
||||
"/v1/workers/{worker_id}/transcript?start={start}&limit={limit}"
|
||||
)) {
|
||||
Ok(response) => {
|
||||
embedded_transcript_projection(&self.runtime_id, worker_id, response.transcript)
|
||||
}
|
||||
Err(diagnostic) => {
|
||||
embedded_transcript_rejected(&self.runtime_id, worker_id, start, limit, diagnostic)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn embedded_runtime_capabilities(
|
||||
@@ -2676,12 +2547,14 @@ fn default_profile_source_archive_http_source(
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
enum ProfileSourceArchiveTransport {
|
||||
Inline,
|
||||
BackendResourceHandle,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
fn default_embedded_config_bundle(
|
||||
profile: &ProfileSelector,
|
||||
workspace_id: &str,
|
||||
@@ -2844,7 +2717,6 @@ fn embedded_input_rejected(
|
||||
state: WorkerOperationState::Rejected,
|
||||
runtime_id: runtime_id.to_string(),
|
||||
worker_id: worker_id.to_string(),
|
||||
transcript_sequence: None,
|
||||
event_id: None,
|
||||
diagnostics: vec![diagnostic],
|
||||
}
|
||||
@@ -2859,7 +2731,6 @@ fn remote_input_rejected(
|
||||
state: WorkerOperationState::Rejected,
|
||||
runtime_id: runtime_id.to_string(),
|
||||
worker_id: worker_id.to_string(),
|
||||
transcript_sequence: None,
|
||||
event_id: None,
|
||||
diagnostics: vec![diagnostic],
|
||||
}
|
||||
@@ -2893,61 +2764,6 @@ fn remote_lifecycle_rejected(
|
||||
}
|
||||
}
|
||||
|
||||
fn embedded_transcript_projection(
|
||||
runtime_id: &str,
|
||||
worker_id: &str,
|
||||
projection: EmbeddedTranscriptProjection,
|
||||
) -> WorkerTranscriptProjection {
|
||||
WorkerTranscriptProjection {
|
||||
state: WorkerOperationState::Accepted,
|
||||
runtime_id: runtime_id.to_string(),
|
||||
worker_id: worker_id.to_string(),
|
||||
start: projection.start,
|
||||
limit: projection.limit,
|
||||
total_items: projection.total_items,
|
||||
next_start: projection.next_start,
|
||||
items: projection
|
||||
.items
|
||||
.into_iter()
|
||||
.map(|item| WorkerTranscriptItem {
|
||||
sequence: item.sequence,
|
||||
role: embedded_transcript_role_label(item.role).to_string(),
|
||||
content: item.content,
|
||||
event_id: item.event_id,
|
||||
})
|
||||
.collect(),
|
||||
diagnostics: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn embedded_transcript_rejected(
|
||||
runtime_id: &str,
|
||||
worker_id: &str,
|
||||
start: usize,
|
||||
limit: usize,
|
||||
diagnostic: RuntimeDiagnostic,
|
||||
) -> WorkerTranscriptProjection {
|
||||
WorkerTranscriptProjection {
|
||||
state: WorkerOperationState::Rejected,
|
||||
runtime_id: runtime_id.to_string(),
|
||||
worker_id: worker_id.to_string(),
|
||||
start,
|
||||
limit,
|
||||
total_items: 0,
|
||||
next_start: None,
|
||||
items: Vec::new(),
|
||||
diagnostics: vec![diagnostic],
|
||||
}
|
||||
}
|
||||
|
||||
fn embedded_transcript_role_label(role: TranscriptRole) -> &'static str {
|
||||
match role {
|
||||
TranscriptRole::User => "user",
|
||||
TranscriptRole::Assistant => "assistant",
|
||||
TranscriptRole::System => "system",
|
||||
}
|
||||
}
|
||||
|
||||
fn embedded_runtime_diagnostic(error: &EmbeddedRuntimeError) -> RuntimeDiagnostic {
|
||||
match error {
|
||||
EmbeddedRuntimeError::RuntimeStopped { .. } => diagnostic(
|
||||
@@ -3814,7 +3630,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn embedded_runtime_with_execution_backend_routes_input_and_projects_transcript() {
|
||||
fn embedded_runtime_with_execution_backend_routes_input_and_updates_status() {
|
||||
let runtime = EmbeddedWorkerRuntime::new_memory_with_execution_backend(
|
||||
"local:test",
|
||||
Arc::new(AcceptingExecutionBackend::default()),
|
||||
@@ -3841,13 +3657,7 @@ mod tests {
|
||||
.worker(&worker.worker_id)
|
||||
.worker
|
||||
.expect("worker detail");
|
||||
let transcript = runtime.transcript(&worker.worker_id, 0, 10);
|
||||
if detail.status == "idle"
|
||||
&& transcript
|
||||
.items
|
||||
.iter()
|
||||
.any(|entry| entry.role == "assistant" && entry.content == "echo: hello")
|
||||
{
|
||||
if detail.status == "idle" {
|
||||
assert!(detail.capabilities.can_accept_input);
|
||||
break;
|
||||
}
|
||||
@@ -3860,7 +3670,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn embedded_runtime_registers_routes_input_and_transcript_without_internal_leaks() {
|
||||
fn embedded_runtime_registers_routes_input_without_internal_leaks() {
|
||||
let registry = RuntimeRegistry::for_workspace(
|
||||
EmbeddedWorkerRuntime::new_memory_with_execution_backend(
|
||||
"local:test",
|
||||
@@ -3933,18 +3743,11 @@ mod tests {
|
||||
assert_eq!(input.runtime_id, EMBEDDED_RUNTIME_ID);
|
||||
assert_eq!(input.worker_id, worker.worker_id);
|
||||
|
||||
let transcript = registry
|
||||
.transcript(EMBEDDED_RUNTIME_ID, &worker.worker_id, 0, 10)
|
||||
let detail = registry
|
||||
.worker(EMBEDDED_RUNTIME_ID, &worker.worker_id)
|
||||
.unwrap();
|
||||
assert_eq!(transcript.state, WorkerOperationState::Accepted);
|
||||
assert!(
|
||||
transcript
|
||||
.items
|
||||
.iter()
|
||||
.any(|entry| entry.role == "user" && entry.content == "hello embedded runtime")
|
||||
);
|
||||
|
||||
let json = serde_json::to_string(&(embedded_summary, worker, transcript)).unwrap();
|
||||
let json = serde_json::to_string(&(embedded_summary, worker, input, detail)).unwrap();
|
||||
for forbidden in [
|
||||
"/workspace/project",
|
||||
"metadata.json",
|
||||
@@ -3953,6 +3756,7 @@ mod tests {
|
||||
"token",
|
||||
"credential",
|
||||
"provider",
|
||||
"transcript",
|
||||
"can_stream_events",
|
||||
"can_read_bounded_transcript",
|
||||
] {
|
||||
@@ -4093,7 +3897,6 @@ mod tests {
|
||||
"ack": {
|
||||
"worker_ref": { "runtime_id": "remote:primary", "worker_id": "worker-remote-1" },
|
||||
"status": "running",
|
||||
"transcript_sequence": 7,
|
||||
"event_id": 8
|
||||
}
|
||||
})
|
||||
@@ -4157,7 +3960,6 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(input.state, WorkerOperationState::Accepted);
|
||||
assert_eq!(input.transcript_sequence, Some(7));
|
||||
assert_eq!(input.event_id, Some(8));
|
||||
|
||||
server.join().expect("mock remote server finished");
|
||||
@@ -4482,7 +4284,6 @@ mod tests {
|
||||
"source_graph": { "source_count": 0, "total_source_bytes": 0, "entrypoints": {}, "import_count": 0 }
|
||||
},
|
||||
"config_bundle": { "id": "remote-bundle", "digest": "remote-digest" },
|
||||
"transcript_len": 0,
|
||||
"last_event_id": 0
|
||||
})
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ use crate::hosts::{
|
||||
RuntimeRegistryUnregisterResult, RuntimeSummary, WorkerInputRequest, WorkerInputResult,
|
||||
WorkerLifecycleRequest, WorkerLifecycleResult, WorkerOperationState,
|
||||
WorkerSpawnAcceptanceRequirement, WorkerSpawnIntent, WorkerSpawnRequest, WorkerSpawnResult,
|
||||
WorkerSpawnWorkingDirectoryRequest, WorkerSummary, WorkerTranscriptProjection,
|
||||
WorkerSpawnWorkingDirectoryRequest, WorkerSummary,
|
||||
};
|
||||
use crate::identity::WorkspaceIdentity;
|
||||
use crate::observation::{
|
||||
@@ -492,14 +492,6 @@ pub fn build_router(api: WorkspaceApi) -> Router {
|
||||
"/api/w/{workspace_id}/runtimes/{runtime_id}/workers/{worker_id}/cancel",
|
||||
post(scoped_cancel_runtime_worker),
|
||||
)
|
||||
.route(
|
||||
"/api/runtimes/{runtime_id}/workers/{worker_id}/transcript",
|
||||
get(get_runtime_worker_transcript),
|
||||
)
|
||||
.route(
|
||||
"/api/w/{workspace_id}/runtimes/{runtime_id}/workers/{worker_id}/transcript",
|
||||
get(scoped_get_runtime_worker_transcript),
|
||||
)
|
||||
.route(
|
||||
"/api/runtimes/{runtime_id}/workers/{worker_id}/events/ws",
|
||||
get(worker_observation_ws),
|
||||
@@ -1498,20 +1490,6 @@ async fn scoped_cancel_runtime_worker(
|
||||
.await
|
||||
}
|
||||
|
||||
async fn scoped_get_runtime_worker_transcript(
|
||||
State(api): State<WorkspaceApi>,
|
||||
AxumPath(path): AxumPath<ScopedRuntimeWorkerPath>,
|
||||
Query(query): Query<TranscriptQuery>,
|
||||
) -> ApiResult<Json<WorkerTranscriptProjection>> {
|
||||
validate_workspace_scope(&api, &path.workspace_id)?;
|
||||
get_runtime_worker_transcript(
|
||||
State(api),
|
||||
AxumPath((path.runtime_id, path.worker_id)),
|
||||
Query(query),
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
async fn scoped_worker_observation_ws(
|
||||
ws: WebSocketUpgrade,
|
||||
State(api): State<WorkspaceApi>,
|
||||
@@ -2245,20 +2223,6 @@ async fn cancel_runtime_worker(
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
async fn get_runtime_worker_transcript(
|
||||
State(api): State<WorkspaceApi>,
|
||||
AxumPath((runtime_id, worker_id)): AxumPath<(String, String)>,
|
||||
Query(query): Query<TranscriptQuery>,
|
||||
) -> ApiResult<Json<WorkerTranscriptProjection>> {
|
||||
let limit = query.limit.unwrap_or(api.config.max_records).min(200);
|
||||
let start = query.start.unwrap_or(0);
|
||||
let result = api
|
||||
.runtime
|
||||
.transcript(&runtime_id, &worker_id, start, limit)
|
||||
.map_err(|err| err.into_error())?;
|
||||
Ok(Json(result))
|
||||
}
|
||||
|
||||
async fn worker_observation_ws(
|
||||
State(api): State<WorkspaceApi>,
|
||||
AxumPath((runtime_id, worker_id)): AxumPath<(String, String)>,
|
||||
@@ -5243,8 +5207,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn embedded_runtime_fs_store_restores_catalog_config_bundle_transcript_and_stale_execution()
|
||||
{
|
||||
async fn embedded_runtime_fs_store_restores_catalog_config_bundle_and_stale_execution() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let config = test_server_config(dir.path().join("workspace"));
|
||||
let store_root = config.embedded_runtime_store_root.clone();
|
||||
@@ -5304,24 +5267,16 @@ mod tests {
|
||||
|
||||
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(2);
|
||||
loop {
|
||||
let transcript = api
|
||||
let detail = api
|
||||
.runtime
|
||||
.transcript("embedded-worker-runtime", &worker_id, 0, 10)
|
||||
.expect("transcript");
|
||||
if transcript.items.iter().any(|item| {
|
||||
item.role == "assistant" && item.content == "server companion echoed: persist me"
|
||||
}) {
|
||||
assert!(
|
||||
transcript
|
||||
.items
|
||||
.iter()
|
||||
.any(|item| item.role == "user" && item.content == "persist me")
|
||||
);
|
||||
.worker("embedded-worker-runtime", &worker_id)
|
||||
.expect("worker detail");
|
||||
if detail.status == "idle" {
|
||||
break;
|
||||
}
|
||||
assert!(
|
||||
std::time::Instant::now() < deadline,
|
||||
"timed out waiting for deterministic transcript"
|
||||
"timed out waiting for deterministic worker completion"
|
||||
);
|
||||
tokio::time::sleep(std::time::Duration::from_millis(10)).await;
|
||||
}
|
||||
@@ -5359,20 +5314,6 @@ mod tests {
|
||||
.any(|summary| summary.id == bundle_id)
|
||||
);
|
||||
|
||||
let restored_transcript = restored
|
||||
.runtime
|
||||
.transcript("embedded-worker-runtime", &worker_id, 0, 10)
|
||||
.expect("restored transcript");
|
||||
assert!(
|
||||
restored_transcript
|
||||
.items
|
||||
.iter()
|
||||
.any(|item| item.role == "user" && item.content == "persist me")
|
||||
);
|
||||
assert!(restored_transcript.items.iter().any(|item| {
|
||||
item.role == "assistant" && item.content == "server companion echoed: persist me"
|
||||
}));
|
||||
|
||||
let rejected_input = restored
|
||||
.runtime
|
||||
.send_input(
|
||||
@@ -5591,15 +5532,20 @@ mod tests {
|
||||
assert_eq!(accepted["worker_id"], worker_id);
|
||||
assert!(accepted["diagnostics"].as_array().unwrap().is_empty());
|
||||
|
||||
let transcript = get_json(
|
||||
app.clone(),
|
||||
&format!("/api/runtimes/embedded-worker-runtime/workers/{worker_id}/transcript?start=0&limit=10"),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(transcript["state"], "accepted");
|
||||
assert!(transcript["items"].as_array().unwrap().iter().any(
|
||||
|item| item["role"] == "user" && item["content"] == "hello from browser-facing api"
|
||||
));
|
||||
let transcript_route = app
|
||||
.clone()
|
||||
.oneshot(
|
||||
Request::builder()
|
||||
.method("GET")
|
||||
.uri(format!(
|
||||
"/api/runtimes/embedded-worker-runtime/workers/{worker_id}/transcript?start=0&limit=10"
|
||||
))
|
||||
.body(Body::empty())
|
||||
.unwrap(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(transcript_route.status(), StatusCode::NOT_FOUND);
|
||||
|
||||
let wrong_runtime = app
|
||||
.clone()
|
||||
@@ -5623,10 +5569,7 @@ mod tests {
|
||||
.unwrap();
|
||||
assert_eq!(wrong_runtime.status(), StatusCode::NOT_FOUND);
|
||||
|
||||
let projected = format!(
|
||||
"{}{}{}{}{}",
|
||||
embedded_summary, spawned, worker, accepted, transcript
|
||||
);
|
||||
let projected = format!("{}{}{}{}", embedded_summary, spawned, worker, accepted);
|
||||
for forbidden in [
|
||||
dir.path().to_string_lossy().as_ref(),
|
||||
"metadata.json",
|
||||
|
||||
Reference in New Issue
Block a user