1pub mod checkpoint;
14pub mod content;
15pub mod reflect;
16
17use bevy_ecs::prelude::*;
18use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
19use rig_core::{
20 completion::{
21 Usage as WireUsage,
22 message::{
23 AssistantContent, AssistantMessage, CallId, Message, ToolChoice, ToolName, UserContent,
24 },
25 },
26 error::ErrorReport,
27 tool::ToolContext,
28};
29use serde::{Deserialize, Serialize};
30
31#[derive(Component, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
34#[reflect(Component)]
35pub struct Owner(pub String);
36
37#[derive(Component, Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Reflect)]
40#[reflect(Component)]
41pub struct Preamble(pub Option<String>);
42
43#[derive(Component, Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize, Reflect)]
45#[reflect(Component)]
46pub struct Temperature(pub Option<f64>);
47
48#[derive(
50 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
51)]
52#[reflect(Component)]
53pub struct MaxTokens(pub Option<u64>);
54
55#[derive(
62 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
63)]
64#[reflect(Component)]
65pub struct AcceptUnknownFinishReasons(pub bool);
66
67#[derive(Component, Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Reflect)]
69#[reflect(Component)]
70pub struct AdditionalParams(
71 #[reflect(remote = crate::agent::reflect::OptionalJsonReflect)] pub Option<serde_json::Value>,
72);
73
74#[derive(Component, Debug, Clone, Default, PartialEq, Serialize, Deserialize, Reflect)]
79#[reflect(opaque, Component, Debug, PartialEq, Serialize, Deserialize)]
80pub struct Options(pub rig_core::completion::GenerationOptions);
81
82#[derive(Component, Debug, Clone, Default, PartialEq, Serialize, Deserialize, Reflect)]
88#[reflect(opaque, Component, Debug, PartialEq, Serialize, Deserialize)]
89pub struct ProviderOptions(pub rig_core::completion::ProviderOptions);
90
91impl ProviderOptions {
92 pub fn set<O: rig_core::completion::ExtensionOptions>(self, options: O) -> Self {
107 Self(self.0.set(options))
108 }
109}
110
111#[derive(Component, Debug, Clone, Default, PartialEq, Serialize, Deserialize, Reflect)]
114#[reflect(Component)]
115pub struct ToolChoiceSpec(
116 #[reflect(remote = crate::agent::reflect::ToolChoiceReflect)] pub Option<ToolChoice>,
117);
118
119#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect)]
121#[serde(rename_all = "snake_case")]
122pub enum OutputKind {
123 #[default]
126 Auto,
127 Native,
130 Tool,
132 Prompted,
134}
135
136#[derive(Component, Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Reflect)]
138#[reflect(Component)]
139pub struct Output {
140 pub mode: OutputKind,
142 #[reflect(remote = crate::agent::reflect::OptionalJsonReflect)]
144 pub schema: Option<serde_json::Value>,
145}
146
147#[derive(Component, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
153#[reflect(Component)]
154pub struct OutputToolConfig {
155 pub name: Option<String>,
157 pub description: Option<String>,
159 pub augment_preamble: bool,
161}
162
163impl Default for OutputToolConfig {
164 fn default() -> Self {
165 Self {
166 name: None,
167 description: None,
168 augment_preamble: true,
169 }
170 }
171}
172
173#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Reflect)]
175#[reflect(Component)]
176pub struct MaxTurns(pub usize);
177
178#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Reflect)]
183#[reflect(Component)]
184pub struct ProviderRetries(pub usize);
185
186pub const DEFAULT_PROVIDER_RETRIES: usize = 3;
188
189#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Reflect)]
194#[reflect(Component)]
195pub struct Backoff {
196 pub base: std::time::Duration,
198 pub max: std::time::Duration,
200}
201
202#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect)]
205#[serde(rename_all = "snake_case")]
206pub enum Unhandled {
207 #[default]
209 Fail,
210 Ignore,
212}
213
214#[derive(
216 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
217)]
218#[reflect(Component)]
219pub struct InvalidCalls {
220 pub retries: usize,
222 pub unhandled: Unhandled,
224}
225
226#[derive(Component, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
232#[reflect(Component)]
233pub struct PolicyVersion(pub String);
234
235#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Reflect)]
239#[reflect(Component)]
240pub struct ToolPolicy {
241 pub concurrency: usize,
243}
244
245impl Default for ToolPolicy {
246 fn default() -> Self {
247 Self { concurrency: 1 }
248 }
249}
250
251#[derive(Component, Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Reflect)]
255#[reflect(Component)]
256pub struct ToolContextSpec(
257 #[reflect(remote = crate::agent::reflect::ToolContextReflect)] pub ToolContext,
258);
259
260#[derive(
263 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
264)]
265#[reflect(Component)]
266pub struct DefaultMaxTurns(pub Option<usize>);
267
268#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
271#[relationship(relationship_target = ModelOf)]
272#[reflect(Component)]
273pub struct UsesModel(pub Entity);
274
275#[derive(Component, Debug, Default, Reflect)]
277#[relationship_target(relationship = UsesModel)]
278#[reflect(Component)]
279pub struct ModelOf(Vec<Entity>);
280
281#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
285#[relationship(relationship_target = RememberedBy)]
286#[reflect(Component)]
287pub struct Remembers(pub Entity);
288
289#[derive(Component, Debug, Default, Reflect)]
291#[relationship_target(relationship = Remembers)]
292#[reflect(Component)]
293pub struct RememberedBy(Vec<Entity>);
294
295#[derive(Component, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
298#[reflect(Component)]
299pub struct Conversation(pub String);
300
301#[derive(
303 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
304)]
305#[reflect(Component)]
306pub struct Remembered;
307
308#[derive(
310 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
311)]
312#[reflect(Component)]
313pub struct Remembering;
314
315#[derive(
320 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
321)]
322#[reflect(Component)]
323pub struct MemoryAppendScheduled;
324
325#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
329#[relationship(relationship_target = RetrievedBy)]
330#[reflect(Component)]
331pub struct Retrieves(pub Entity);
332
333#[derive(Component, Debug, Default, Reflect)]
335#[relationship_target(relationship = Retrieves)]
336#[reflect(Component)]
337pub struct RetrievedBy(Vec<Entity>);
338
339#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Reflect)]
341#[reflect(Component)]
342pub struct Retrieval {
343 pub samples: u64,
345 pub what: RetrievalKind,
347}
348
349#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Reflect)]
351#[serde(rename_all = "snake_case")]
352pub enum RetrievalKind {
353 Documents,
355 Tools,
357}
358
359#[derive(
361 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
362)]
363#[reflect(Component)]
364pub struct Retrievable;
365
366#[derive(
368 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
369)]
370#[reflect(Component)]
371pub struct Retrieving;
372
373#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
377#[relationship(relationship_target = RoutedTo)]
378#[reflect(Component)]
379pub struct Route(pub Entity);
380
381#[derive(Component, Debug, Default, Reflect)]
383#[relationship_target(relationship = Route)]
384#[reflect(Component)]
385pub struct RoutedTo(Vec<Entity>);
386
387#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
390#[relationship(relationship_target = Grants)]
391#[reflect(Component)]
392pub struct Grant(pub Entity);
393
394#[derive(Component, Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Reflect)]
403#[reflect(opaque, Component, Debug, PartialEq, Serialize, Deserialize)]
404pub struct ToolAccess {
405 pub executable: Option<std::collections::BTreeMap<String, rig_core::effect::HandlerKey>>,
408 pub allowed: Option<std::collections::BTreeSet<String>>,
412}
413
414#[derive(Component, Debug, Default, Reflect)]
416#[relationship_target(relationship = Grant)]
417#[reflect(Component)]
418pub struct Grants(Vec<Entity>);
419
420#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
423#[relationship(relationship_target = ContextOf)]
424#[reflect(Component)]
425pub struct Context(pub Entity);
426
427#[derive(Component, Debug, Default, Reflect)]
429#[relationship_target(relationship = Context)]
430#[reflect(Component)]
431pub struct ContextOf(Vec<Entity>);
432
433#[derive(Component, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
435#[reflect(Component)]
436pub struct DocumentId(pub String);
437
438#[derive(Component, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
440#[reflect(Component)]
441pub struct DocumentText(pub String);
442
443#[derive(Component, Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Reflect)]
445#[reflect(Component)]
446pub struct DocumentProps(pub std::collections::HashMap<String, String>);
447
448#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
451#[relationship(relationship_target = AttachedTo)]
452#[reflect(Component)]
453pub struct Attachment(pub Entity);
454
455#[derive(Component, Debug, Default, Reflect)]
457#[relationship_target(relationship = Attachment)]
458#[reflect(Component)]
459pub struct AttachedTo(Vec<Entity>);
460
461#[derive(
465 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
466)]
467#[reflect(Component)]
468pub struct Utterance;
469
470#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Reflect)]
472#[serde(rename_all = "snake_case")]
473#[reflect(Component)]
474pub enum Role {
475 User,
477 Assistant,
479}
480
481#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
484#[serde(tag = "role", rename_all = "snake_case")]
485#[reflect(opaque, Debug, PartialEq, Serialize, Deserialize)]
486pub enum MessageParts {
487 User {
489 content: Vec<UserContent>,
491 },
492 Assistant(AssistantMessage),
494}
495
496impl MessageParts {
497 pub fn user(content: Vec<UserContent>) -> Result<Self, content::parts::ContentError> {
502 if content.is_empty() {
503 return Err(content::parts::ContentError::Shape);
504 }
505 Ok(Self::User { content })
506 }
507
508 pub fn assistant(message: AssistantMessage) -> Result<Self, content::parts::ContentError> {
513 if message.content.is_empty() {
514 return Err(content::parts::ContentError::Shape);
515 }
516 Ok(Self::Assistant(message))
517 }
518
519 pub fn to_message(&self) -> Message {
521 match self {
522 Self::User { content } => Message::User {
523 content: content.clone(),
524 },
525 Self::Assistant(message) => Message::Assistant(message.clone()),
526 }
527 }
528
529 pub fn from_message(message: &Message) -> Option<Self> {
532 match message {
533 Message::System { .. } => None,
534 Message::User { content } => Some(Self::User {
535 content: content.clone(),
536 }),
537 Message::Assistant(message) => Some(Self::Assistant(message.clone())),
538 }
539 }
540
541 pub fn role(&self) -> Role {
543 match self {
544 Self::User { .. } => Role::User,
545 Self::Assistant { .. } => Role::Assistant,
546 }
547 }
548}
549
550#[derive(Component, Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
554#[reflect(Component, opaque, Debug, PartialEq, Serialize, Deserialize)]
555pub struct Prompt(pub Vec<UserContent>);
556
557#[derive(
561 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
562)]
563#[reflect(Component)]
564pub struct Ready;
565
566impl From<&str> for Prompt {
567 fn from(text: &str) -> Self {
568 Self(vec![UserContent::text(text)])
569 }
570}
571
572impl From<String> for Prompt {
573 fn from(text: String) -> Self {
574 Self(vec![UserContent::text(text)])
575 }
576}
577
578impl From<UserContent> for Prompt {
579 fn from(part: UserContent) -> Self {
580 Self(vec![part])
581 }
582}
583
584impl From<Vec<UserContent>> for Prompt {
585 fn from(parts: Vec<UserContent>) -> Self {
586 Self(parts)
587 }
588}
589
590#[derive(
595 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
596)]
597#[require(
598 Cursor,
599 OutputRetries,
600 InvalidRetries,
601 ProviderRetried,
602 OutputToolName,
603 Usage,
604 StreamRequested
605)]
606#[component(on_add = stamp_run)]
607#[reflect(Component)]
608pub struct Run;
609
610fn stamp_run(
611 mut world: bevy_ecs::world::DeferredWorld<'_>,
612 context: bevy_ecs::lifecycle::HookContext,
613) {
614 let entity = context.entity;
615 if world.get::<RunSeq>(entity).is_none()
618 && let Some(mut counter) = world.get_resource_mut::<RunCounter>()
619 {
620 let seq = counter.0;
621 counter.0 += 1;
622 let owner = world
623 .get::<RunOf>(entity)
624 .and_then(|run_of| world.get::<Owner>(run_of.0))
625 .map(|owner| owner.0.clone())
626 .unwrap_or_default();
627 world
628 .commands()
629 .entity(entity)
630 .insert((RunSeq(seq), crate::bus::Scope(format!("{owner}/run#{seq}"))));
631 }
632}
633
634#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
636#[relationship(relationship_target = Runs)]
637#[reflect(Component)]
638pub struct RunOf(pub Entity);
639
640#[derive(Component, Debug, Default, Reflect)]
642#[relationship_target(relationship = RunOf)]
643#[reflect(Component)]
644pub struct Runs(Vec<Entity>);
645
646impl Runs {
647 pub fn runs(&self) -> &[Entity] {
649 &self.0
650 }
651}
652
653#[derive(
657 Component,
658 Debug,
659 Clone,
660 Copy,
661 Default,
662 PartialEq,
663 Eq,
664 PartialOrd,
665 Ord,
666 Serialize,
667 Deserialize,
668 Reflect,
669)]
670#[reflect(Component)]
671pub struct RunSeq(pub u64);
672
673#[derive(Resource, Debug, Default, Reflect)]
675#[reflect(Resource)]
676pub struct RunCounter(pub(crate) u64);
677
678#[derive(
680 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
681)]
682#[reflect(Component)]
683pub struct StreamRequested(pub bool);
684
685#[derive(
687 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
688)]
689#[reflect(Component)]
690pub struct Cursor {
691 pub turn: usize,
693}
694
695#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Reflect)]
700#[component(immutable)]
701#[serde(rename_all = "snake_case")]
702#[reflect(Component)]
703pub enum RunPhase {
704 LoadingMemory,
706 Assembling,
708 AwaitingModel,
710 ResolvingTools,
713}
714
715#[derive(
718 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
719)]
720#[reflect(Component)]
721pub struct Batch {
722 pub calls: usize,
724}
725
726#[derive(Component, Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
729#[reflect(Component)]
730pub struct ToolCallSlot {
731 pub index: usize,
733 #[reflect(remote = crate::agent::reflect::ToolCallIdReflect)]
735 pub id: CallId,
736 #[reflect(remote = crate::agent::reflect::ToolNameReflect)]
738 pub name: ToolName,
739}
740
741#[derive(
743 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
744)]
745#[reflect(Component)]
746pub struct Settled;
747
748#[derive(Component, Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
750#[reflect(Component)]
751pub struct Failed(pub Failure);
752
753#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
755#[serde(tag = "failure", rename_all = "snake_case")]
756#[reflect(opaque, Debug, PartialEq, Serialize, Deserialize)]
757pub enum Failure {
758 Content(content::parts::ContentError),
760 MaxTurns {
762 limit: usize,
764 },
765 UnknownToolCall {
768 name: String,
770 },
771 Provider(ErrorReport),
773 Cancelled(ErrorReport),
776 Unsupported(String),
779 OutputToolCollision {
781 name: String,
783 },
784 Tool(ErrorReport),
787 Memory(ErrorReport),
790}
791
792#[derive(Component, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
794#[reflect(Component)]
795pub struct RunResult(pub String);
796
797#[derive(Component, Debug, Clone, Copy, Default, PartialEq, Serialize, Deserialize, Reflect)]
799#[reflect(Component)]
800pub struct Usage(#[reflect(remote = crate::agent::reflect::UsageReflect)] pub WireUsage);
801
802#[derive(
804 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
805)]
806#[reflect(Component)]
807pub struct OutputRetries(pub usize);
808
809#[derive(
811 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
812)]
813#[reflect(Component)]
814pub struct InvalidRetries(pub usize);
815
816#[derive(
818 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
819)]
820#[reflect(Component)]
821pub struct ProviderRetried(pub usize);
822
823#[derive(
827 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
828)]
829#[reflect(Component)]
830pub struct ProviderRetrying;
831
832#[derive(Component, Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Reflect)]
834#[reflect(Component)]
835pub struct OutputToolName(pub Option<String>);
836
837#[derive(
839 Component, Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, Reflect,
840)]
841#[reflect(Component)]
842pub struct Turn;
843
844#[derive(Component, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
847#[relationship(relationship_target = AdvertisedOn)]
848#[reflect(Component)]
849pub struct Advert(pub Entity);
850
851#[derive(Component, Debug, Default, Reflect)]
853#[relationship_target(relationship = Advert)]
854#[reflect(Component)]
855pub struct AdvertisedOn(Vec<Entity>);
856
857#[derive(Component, Debug, Clone, Default, PartialEq, Serialize, Deserialize, Reflect)]
860#[reflect(Component)]
861pub struct Outputs {
862 #[reflect(remote = crate::agent::reflect::AssistantContentsReflect)]
864 pub content: Vec<AssistantContent>,
865 pub head: content::parts::AssistantHead,
867 pub done: bool,
869 pub usage_recorded: bool,
872 pub stream_validated: usize,
874}
875
876#[derive(Component, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
882#[reflect(Component)]
883pub struct Cancelled(pub String);
884
885#[derive(Component, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
890#[reflect(Component)]
891pub struct Retry {
892 pub feedback: Option<String>,
894}
895
896#[derive(Component, Debug, Clone, Default, PartialEq, Serialize, Deserialize, Reflect)]
903#[reflect(opaque, Component, Debug, PartialEq, Serialize, Deserialize)]
904pub struct RequestPatch {
905 pub preamble: Option<String>,
908 pub temperature: Option<f64>,
910 pub max_tokens: Option<u64>,
912 pub tool_choice: Option<ToolChoice>,
914 pub active_tools: Option<Vec<String>>,
916 pub additional_params: Option<serde_json::Value>,
919 pub extra_context: Vec<rig_core::completion::Document>,
921 pub history: Option<Vec<MessageParts>>,
923}
924
925impl RequestPatch {
926 #[must_use = "the merged patch is the returned value"]
931 pub fn merge(mut self, later: Self) -> Self {
932 self.extra_context.extend(later.extra_context);
933 self.additional_params = match (self.additional_params.take(), later.additional_params) {
934 (Some(base), Some(patch)) if base.is_object() && patch.is_object() => {
935 Some(rig_core::json_utils::merge(base, patch))
936 }
937 (base, patch) => patch.or(base),
938 };
939 self.preamble = later.preamble.or(self.preamble);
940 self.temperature = later.temperature.or(self.temperature);
941 self.max_tokens = later.max_tokens.or(self.max_tokens);
942 self.tool_choice = later.tool_choice.or(self.tool_choice);
943 self.history = later.history.or(self.history);
944 self.active_tools = match (self.active_tools.take(), later.active_tools) {
945 (Some(earlier), Some(later)) => Some(
946 earlier
947 .into_iter()
948 .filter(|name| later.contains(name))
949 .collect(),
950 ),
951 (earlier, later) => earlier.or(later),
952 };
953 self
954 }
955}
956
957#[derive(Component, Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
960#[reflect(Component)]
961pub struct Reprompt(#[reflect(remote = crate::agent::reflect::MessageReflect)] pub Message);
962
963#[derive(Component, Debug, Clone, PartialEq, Serialize, Deserialize, Reflect)]
966#[reflect(Component)]
967pub struct InvalidCall {
968 #[reflect(remote = crate::agent::reflect::ToolCallIdReflect)]
970 pub id: CallId,
971 pub name: String,
973 #[reflect(remote = crate::agent::reflect::JsonReflect)]
975 pub arguments: serde_json::Value,
976 #[serde(default, skip_serializing_if = "Vec::is_empty")]
979 #[reflect(remote = crate::agent::reflect::AssistantContentsReflect)]
980 pub prefix: Vec<AssistantContent>,
981 #[serde(default, skip_serializing_if = "Option::is_none")]
984 pub stream_offset: Option<usize>,
985 #[serde(default, skip_serializing_if = "Option::is_none")]
989 #[reflect(remote = crate::agent::content::reflect::OriginReflect)]
990 pub origin: Option<rig_core::message::Origin>,
991}
992
993#[derive(Component, Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Reflect)]
997#[serde(tag = "resolution", rename_all = "snake_case")]
998#[reflect(Component)]
999pub enum Resolution {
1000 Fail,
1002 Ignore,
1004 Retry {
1010 feedback: String,
1012 },
1013 Repair {
1015 to: String,
1017 },
1018 Skip {
1022 reason: String,
1024 },
1025}
1026
1027const _: () = {
1030 const fn assert_serde<T: Serialize + serde::de::DeserializeOwned>() {}
1031 assert_serde::<Owner>();
1032 assert_serde::<Preamble>();
1033 assert_serde::<Output>();
1034 assert_serde::<Failed>();
1035 assert_serde::<Outputs>();
1036 assert_serde::<InvalidCall>();
1037 assert_serde::<Resolution>();
1038 assert_serde::<ToolPolicy>();
1039 assert_serde::<ToolContextSpec>();
1040 assert_serde::<Batch>();
1041 assert_serde::<ToolCallSlot>();
1042 assert_serde::<Cancelled>();
1043 assert_serde::<Retry>();
1044 assert_serde::<RequestPatch>();
1045 assert_serde::<Conversation>();
1046 assert_serde::<Retrieval>();
1047};
1048
1049pub fn fork(world: &mut World, run: Entity) -> Entity {
1054 let seq = {
1055 let mut counter = world.resource_mut::<RunCounter>();
1056 let seq = counter.0;
1057 counter.0 += 1;
1058 seq
1059 };
1060 let owner = world
1061 .get::<RunOf>(run)
1062 .and_then(|run_of| world.get::<Owner>(run_of.0))
1063 .map(|owner| owner.0.clone())
1064 .unwrap_or_default();
1065 use bevy_ecs::entity::{EntityCloner, EntityHashMap};
1069 use checkpoint::{AssistantForTurns, ResultsForTurns, TurnAssistant, TurnResults};
1070 let links: Vec<_> = world
1071 .query::<(
1072 Entity,
1073 &ChildOf,
1074 Option<&TurnAssistant>,
1075 Option<&TurnResults>,
1076 )>()
1077 .iter(world)
1078 .filter(|(_, parent, _, _)| parent.parent() == run)
1079 .map(|(turn, _, assistant, results)| (turn, assistant.copied(), results.copied()))
1080 .collect();
1081 let clone = world.spawn_empty().id();
1082 let mut mapped = EntityHashMap::default();
1083 mapped.insert(run, clone);
1084 let mut cloner = EntityCloner::build_opt_out(world);
1085 cloner.linked_cloning(true).deny::<(
1086 crate::bus::PendingEffect,
1087 crate::bus::Seq,
1088 crate::bus::Issued,
1089 crate::bus::Reserved,
1090 crate::bus::EffectOutcome,
1091 crate::bus::ToolInputs,
1092 crate::bus::ToolOutputs,
1093 ToolCallSlot,
1094 TurnAssistant,
1095 AssistantForTurns,
1096 TurnResults,
1097 ResultsForTurns,
1098 )>();
1099 cloner.finish().clone_entity_mapped(world, run, &mut mapped);
1100 world.flush();
1101 for (turn, assistant, results) in links {
1102 if let Some(turn) = mapped.get(&turn).copied() {
1103 if let Some(TurnAssistant(target)) = assistant {
1104 let target = mapped.get(&target).copied().unwrap_or(target);
1105 world.entity_mut(turn).insert(TurnAssistant(target));
1106 }
1107 if let Some(TurnResults(target)) = results {
1108 let target = mapped.get(&target).copied().unwrap_or(target);
1109 world.entity_mut(turn).insert(TurnResults(target));
1110 }
1111 }
1112 }
1113 world
1114 .entity_mut(clone)
1115 .insert((RunSeq(seq), crate::bus::Scope(format!("{owner}/run#{seq}"))));
1116 clone
1117}
1118
1119#[cfg(test)]
1120mod tests;