1use std::cell::RefCell;
21use std::collections::{BTreeMap, BTreeSet, VecDeque};
22use std::rc::Rc;
23
24use crate::budget::{Budget, BudgetMeter};
25use crate::cap::{CapAttrs, CapControl, CapHandle, CapId, CapRecord, ProviderId, ToolPolicy};
26use crate::channel::{Channel, ChannelId, Direction, Message};
27use crate::error::{Error, Result};
28use crate::lane::{Lane, LaneId};
29use crate::promise::{PromiseId, PromiseRecord, PromiseState};
30use crate::value::{Arg, Call, Response, Value};
31
32pub trait Provider {
34 fn name(&self) -> &'static str;
36 fn methods(&self) -> Vec<String>;
38 fn has_method(&self, method: &str) -> bool {
40 self.methods().iter().any(|name| name == method)
41 }
42 fn mutating(&self, method: &str) -> bool;
44 fn invoke(&mut self, object: u64, call: &Call) -> Result<Response>;
46 fn on_drop(&mut self, _object: u64, _cap: CapId) {}
48
49 fn take_drop_notifications(&mut self) -> Vec<(u64, CapId)> {
54 Vec::new()
55 }
56}
57
58#[derive(Debug, Clone, PartialEq)]
60pub enum Event {
61 CapMinted {
63 cap: CapId,
65 provider: ProviderId,
67 },
68 CapRetained(CapId),
70 CapReleased(CapId),
72 CapDropped(CapId),
74 CapRevoked(CapId),
76 LaneCreated(LaneId),
78 LaneDestroyed(LaneId),
80 CallQueued {
82 job: u64,
84 lane: LaneId,
86 cap: CapId,
88 },
89 BatchDispatched {
91 provider: ProviderId,
93 jobs: usize,
95 lanes: BTreeSet<u64>,
97 },
98 JobCompleted {
100 job: u64,
102 lane: LaneId,
104 },
105 PromiseResolved(PromiseId),
107 PromiseRejected {
109 promise: PromiseId,
111 code: String,
113 },
114 ChannelSend {
116 channel: ChannelId,
118 sequence: u64,
120 },
121 ChannelRecv {
123 channel: ChannelId,
125 sequence: u64,
127 },
128 CapTransferred {
130 cap: CapId,
132 channel: ChannelId,
134 },
135}
136
137#[derive(Debug, Clone, Copy, PartialEq, Eq)]
138enum JobState {
139 Queued,
140 Done,
141}
142
143#[derive(Debug, Clone)]
144struct Job {
145 #[allow(dead_code)]
146 id: u64,
147 lane: LaneId,
148 cap: CapId,
149 call: Call,
150 deps: Vec<PromiseId>,
151 promise: PromiseId,
152 state: JobState,
153}
154
155pub struct Kernel {
156 secret: [u8; 32],
157 providers: BTreeMap<ProviderId, Box<dyn Provider>>,
158 caps: BTreeMap<CapId, CapRecord>,
159 meters: BTreeMap<CapId, BudgetMeter>,
160 promises: BTreeMap<PromiseId, PromiseRecord>,
161 lanes: BTreeMap<LaneId, Lane>,
162 channels: BTreeMap<ChannelId, Channel>,
163 jobs: BTreeMap<u64, Job>,
164 queue: VecDeque<u64>,
165 events: Vec<Event>,
166 round_trips: u64,
167 next_promise: u64,
168 next_job: u64,
169 next_lane: u64,
170 next_channel: u64,
171 next_serial: u64,
172 next_provider: u64,
173 now_ms: u64,
174 latency_ms: u64,
175 transfers: u64,
176}
177
178pub(crate) struct HandleControl {
182 cell: KernelCell,
183}
184
185impl HandleControl {
186 fn new(cell: KernelCell) -> Self {
187 Self { cell }
188 }
189}
190
191impl CapControl for HandleControl {
192 fn retain(&self, id: CapId) {
193 if let Ok(mut kernel) = self.cell.try_borrow_mut() {
194 if let Some(record) = kernel.caps.get_mut(&id) {
195 record.refs = record.refs.saturating_add(1);
196 kernel.events.push(Event::CapRetained(id));
197 }
198 }
199 }
200
201 fn release(&self, id: CapId) {
202 let dropped = {
203 let Ok(mut kernel) = self.cell.try_borrow_mut() else {
204 return;
205 };
206 let Some(record) = kernel.caps.get_mut(&id) else {
207 return;
208 };
209 record.refs = record.refs.saturating_sub(1);
210 let last = record.refs == 0;
211 kernel.events.push(Event::CapReleased(id));
212 last
213 };
214 if !dropped {
215 return;
216 }
217 let mut kernel = self.cell.borrow_mut();
218 let Some(record) = kernel.caps.remove(&id) else {
219 return;
220 };
221 kernel.meters.remove(&id);
222 kernel.events.push(Event::CapDropped(id));
223 if let Some(provider) = kernel.providers.get_mut(&record.provider) {
224 provider.on_drop(record.object, id);
225 }
226 }
227}
228
229pub type KernelCell = Rc<RefCell<Kernel>>;
231
232#[derive(Clone)]
234pub struct Agent {
235 cell: KernelCell,
236 control: Rc<dyn CapControl>,
237}
238
239impl Default for Agent {
240 fn default() -> Self {
241 Self::new()
242 }
243}
244
245impl Agent {
246 pub fn new() -> Self {
252 let mut seed = [0u8; 32];
253 getrandom::fill(&mut seed).expect("the operating system CSPRNG must be available");
254 Self::with_secret(seed)
255 }
256
257 pub fn with_secret(secret: [u8; 32]) -> Self {
259 let kernel = Kernel {
260 secret,
261 providers: BTreeMap::new(),
262 caps: BTreeMap::new(),
263 meters: BTreeMap::new(),
264 promises: BTreeMap::new(),
265 lanes: BTreeMap::new(),
266 channels: BTreeMap::new(),
267 jobs: BTreeMap::new(),
268 queue: VecDeque::new(),
269 events: Vec::new(),
270 round_trips: 0,
271 next_promise: 0,
272 next_job: 0,
273 next_lane: 0,
274 next_channel: 0,
275 next_serial: 0,
276 next_provider: 0,
277 now_ms: 0,
278 latency_ms: 1,
279 transfers: 0,
280 };
281 let cell: KernelCell = Rc::new(RefCell::new(kernel));
282 let control: Rc<dyn CapControl> = Rc::new(HandleControl::new(Rc::clone(&cell)));
283 Agent { cell, control }
284 }
285
286 pub fn cell(&self) -> &KernelCell {
288 &self.cell
289 }
290
291 pub fn register(&self, provider: Box<dyn Provider>) -> ProviderId {
293 let mut kernel = self.cell.borrow_mut();
294 let id = ProviderId(kernel.next_provider);
295 kernel.next_provider += 1;
296 kernel.providers.insert(id, provider);
297 id
298 }
299
300 pub fn set_latency(&self, latency_ms: u64) {
302 self.cell.borrow_mut().latency_ms = latency_ms;
303 }
304
305 pub fn mint(&self, provider: ProviderId, object: u64, attrs: CapAttrs) -> Result<CapHandle> {
307 attrs.budget.check()?;
308 if attrs.methods.is_empty() {
309 return Err(Error::InvalidArgument("capability grants no methods"));
310 }
311 let mut kernel = self.cell.borrow_mut();
312 if !kernel.providers.contains_key(&provider) {
313 return Err(Error::InvalidArgument("unknown provider"));
314 }
315 let serial = kernel.next_serial;
316 kernel.next_serial += 1;
317 let id = CapId::derive(&kernel.secret, serial, None);
318 let record = CapRecord::new(id, provider, object, attrs.clone());
319 kernel.meters.insert(id, BudgetMeter::new(attrs.budget));
320 kernel.caps.insert(id, record);
321 kernel.events.push(Event::CapMinted { cap: id, provider });
322 Ok(CapHandle::new(Rc::clone(&self.control), id))
323 }
324
325 pub fn attenuate(&self, parent: &CapHandle, attrs: CapAttrs) -> Result<CapHandle> {
327 let parent_id = parent.id();
328 let mut kernel = self.cell.borrow_mut();
329 let record = kernel
330 .caps
331 .get(&parent_id)
332 .ok_or(Error::UnknownCapability(u128::from_be_bytes(pad128(
333 parent_id,
334 ))))?
335 .clone();
336 if record.revoked {
337 return Err(Error::Revoked(u128::from_be_bytes(pad128(parent_id))));
338 }
339 let attrs = record.attrs.attenuate(attrs)?;
340 let serial = kernel.next_serial;
341 kernel.next_serial += 1;
342 let id = CapId::derive(&kernel.secret, serial, Some(&parent_id));
343 let mut child = CapRecord::new(id, record.provider, record.object, attrs.clone());
344 child.parent = Some(parent_id);
345 kernel.meters.insert(id, BudgetMeter::new(attrs.budget));
346 kernel.caps.insert(id, child);
347 kernel.events.push(Event::CapMinted {
348 cap: id,
349 provider: record.provider,
350 });
351 Ok(CapHandle::new(Rc::clone(&self.control), id))
352 }
353
354 pub fn import(&self, id: CapId) -> CapHandle {
361 CapHandle::borrowed(Rc::clone(&self.control), id)
362 }
363
364 pub fn revoke(&self, cap: &CapHandle) {
366 let mut kernel = self.cell.borrow_mut();
367 let mut doomed = BTreeSet::new();
368 let mut stack = vec![cap.id()];
369 while let Some(id) = stack.pop() {
370 if !doomed.insert(id) {
371 continue;
372 }
373 for (child, record) in &kernel.caps {
374 if record.parent == Some(id) {
375 stack.push(*child);
376 }
377 }
378 }
379 for id in doomed {
380 if let Some(record) = kernel.caps.get_mut(&id) {
381 record.revoked = true;
382 }
383 kernel.events.push(Event::CapRevoked(id));
384 }
385 }
386
387 pub fn create_lane(&self, name: impl Into<String>, budget: Budget) -> Result<LaneId> {
389 budget.check()?;
390 let mut kernel = self.cell.borrow_mut();
391 let id = LaneId(kernel.next_lane);
392 kernel.next_lane += 1;
393 kernel.lanes.insert(id, Lane::new(id, name, budget));
394 kernel.events.push(Event::LaneCreated(id));
395 Ok(id)
396 }
397
398 pub fn attenuate_lane(&self, lane: LaneId, budget: Budget) -> Result<()> {
400 let mut kernel = self.cell.borrow_mut();
401 let record = kernel
402 .lanes
403 .get_mut(&lane)
404 .ok_or(Error::UnknownLane(lane.0))?;
405 record.attenuate(budget)
406 }
407
408 pub fn destroy_lane(&self, lane: LaneId) -> Result<()> {
414 let mut kernel = self.cell.borrow_mut();
415 {
416 let record = kernel
417 .lanes
418 .get_mut(&lane)
419 .ok_or(Error::UnknownLane(lane.0))?;
420 record.destroy();
421 }
422 let doomed: Vec<u64> = kernel
423 .jobs
424 .iter()
425 .filter(|(_, job)| job.lane == lane && job.state == JobState::Queued)
426 .map(|(id, _)| *id)
427 .collect();
428 kernel.queue.retain(|id| !doomed.contains(id));
429 for job_id in doomed {
430 kernel.fail_job(job_id, Error::UnknownLane(lane.0));
431 }
432 kernel.events.push(Event::LaneDestroyed(lane));
433 Ok(())
434 }
435
436 pub fn create_channel(
438 &self,
439 name: impl Into<String>,
440 direction: Direction,
441 ) -> Result<ChannelId> {
442 let mut kernel = self.cell.borrow_mut();
443 let id = ChannelId(kernel.next_channel);
444 kernel.next_channel += 1;
445 kernel
446 .channels
447 .insert(id, Channel::new(id, name, direction));
448 Ok(id)
449 }
450
451 pub fn subscribe(&self, lane: LaneId, channel: ChannelId) -> Result<()> {
453 let mut kernel = self.cell.borrow_mut();
454 if !kernel.lanes.contains_key(&lane) {
455 return Err(Error::UnknownLane(lane.0));
456 }
457 let record = kernel
458 .channels
459 .get_mut(&channel)
460 .ok_or(Error::UnknownChannel(channel.0))?;
461 record.subscribers.insert(lane.0);
462 if let Some(lane) = kernel.lanes.get_mut(&lane) {
463 lane.channels.insert(channel.0);
464 }
465 Ok(())
466 }
467
468 pub fn send(
470 &self,
471 lane: LaneId,
472 channel: ChannelId,
473 payload: Value,
474 caps: &[CapHandle],
475 ) -> Result<u64> {
476 let mut kernel = self.cell.borrow_mut();
477 if !kernel.lanes.contains_key(&lane) {
478 return Err(Error::UnknownLane(lane.0));
479 }
480 let mut cap_ids = Vec::with_capacity(caps.len());
481 for cap in caps {
482 let record = kernel
483 .caps
484 .get(&cap.id())
485 .ok_or(Error::InvalidArgument("unknown capability"))?;
486 if record.revoked {
487 return Err(Error::Revoked(u128::from_be_bytes(pad128(cap.id()))));
488 }
489 cap_ids.push(cap.id());
493 }
494 let record = kernel
495 .channels
496 .get_mut(&channel)
497 .ok_or(Error::UnknownChannel(channel.0))?;
498 let message = record.send(lane, payload, cap_ids.clone())?;
499 kernel.events.push(Event::ChannelSend {
500 channel,
501 sequence: message.sequence,
502 });
503 for id in cap_ids {
504 if let Some(record) = kernel.caps.get_mut(&id) {
505 record.refs = record.refs.saturating_add(1);
506 }
507 kernel.transfers += 1;
508 kernel
509 .events
510 .push(Event::CapTransferred { cap: id, channel });
511 }
512 Ok(message.sequence)
513 }
514
515 pub fn recv(&self, channel: ChannelId) -> Result<Option<Message>> {
517 let mut kernel = self.cell.borrow_mut();
518 let record = kernel
519 .channels
520 .get_mut(&channel)
521 .ok_or(Error::UnknownChannel(channel.0))?;
522 let message = record.recv()?;
523 if let Some(message) = &message {
524 kernel.events.push(Event::ChannelRecv {
525 channel,
526 sequence: message.sequence,
527 });
528 }
529 Ok(message)
530 }
531
532 pub fn call(
534 &self,
535 lane: LaneId,
536 cap: &CapHandle,
537 method: &str,
538 args: Vec<Arg>,
539 ) -> Result<PromiseHandle> {
540 let mut kernel = self.cell.borrow_mut();
541 let cap_id = cap.id();
542 let record = kernel
543 .caps
544 .get(&cap_id)
545 .ok_or(Error::UnknownCapability(u128::from_be_bytes(pad128(
546 cap_id,
547 ))))?
548 .clone();
549 if record.revoked {
550 return Err(Error::Revoked(u128::from_be_bytes(pad128(cap_id))));
551 }
552 let (lane_closed, lane_capacity, lane_budget) = {
553 let lane_record = kernel.lanes.get(&lane).ok_or(Error::UnknownLane(lane.0))?;
554 (
555 lane_record.closed,
556 lane_record.has_capacity(),
557 lane_record.budget,
558 )
559 };
560 if lane_closed {
561 return Err(Error::UnknownLane(lane.0));
562 }
563 if !lane_capacity {
564 return Err(Error::BudgetExceeded("lane call"));
565 }
566 if !record.attrs.grants(method) {
567 return Err(Error::MethodNotGranted {
568 method: method.to_string(),
569 });
570 }
571 let provider = kernel
572 .providers
573 .get(&record.provider)
574 .ok_or(Error::InvalidArgument("provider disappeared"))?;
575 if !provider.has_method(method) {
576 return Err(Error::MethodNotGranted {
577 method: method.to_string(),
578 });
579 }
580 if record.attrs.read_only && provider.mutating(method) {
581 return Err(Error::ReadOnly);
582 }
583 if let Some(scope) = &record.attrs.path_scope {
585 for arg in &args {
586 if let Arg::Value(Value::Path(path)) = arg {
587 if !crate::cap::is_path_prefix(scope, path) {
588 return Err(Error::PathNotGranted(path.clone()));
589 }
590 }
591 }
592 }
593 if let Some(policy) = &record.attrs.tool_policy {
595 if !policy.allowed.contains(method) {
596 return Err(Error::ToolPolicy("tool not allowed"));
597 }
598 let bytes: u64 = args
599 .iter()
600 .map(|arg| match arg {
601 Arg::Value(Value::Text(text)) => text.len() as u64,
602 Arg::Value(Value::Module(bytes)) => bytes.len() as u64,
603 _ => 0,
604 })
605 .sum();
606 if bytes > policy.max_arg_bytes {
607 return Err(Error::ToolPolicy("argument too large"));
608 }
609 }
610 let call_bytes: u64 = args.iter().map(|arg| arg.wire_size()).sum();
611 let effective = record.attrs.budget.intersect(&lane_budget);
612 if call_bytes > effective.max_bytes {
613 return Err(Error::BudgetExceeded("byte"));
614 }
615 let meter = kernel
616 .meters
617 .get_mut(&cap_id)
618 .ok_or(Error::InvalidArgument("capability has no meter"))?;
619 meter.charge(call_bytes)?;
620
621 let promise_id = PromiseId(kernel.next_promise);
622 kernel.next_promise += 1;
623 kernel
624 .promises
625 .insert(promise_id, PromiseRecord::new(promise_id, lane.0));
626 let job_id = kernel.next_job;
627 kernel.next_job += 1;
628 let deps: Vec<PromiseId> = args.iter().filter_map(|arg| arg.promise()).collect();
629 for dep in &deps {
630 if !kernel.promises.contains_key(dep) {
631 return Err(Error::UnknownPromise(dep.0));
632 }
633 if let Some(record) = kernel.promises.get_mut(dep) {
634 record.waiters += 1;
635 }
636 }
637 let call = Call {
638 method: method.to_string(),
639 args,
640 path_scope: record.attrs.path_scope.clone(),
641 redact: record.attrs.redact,
642 read_only: record.attrs.read_only,
643 tool_allows_process: record
644 .attrs
645 .tool_policy
646 .as_ref()
647 .map(|policy| policy.allow_process)
648 .unwrap_or(false),
649 budget: effective,
650 };
651 let job = Job {
652 id: job_id,
653 lane,
654 cap: cap_id,
655 call,
656 deps,
657 promise: promise_id,
658 state: JobState::Queued,
659 };
660 kernel.jobs.insert(job_id, job);
661 kernel.queue.push_back(job_id);
662 if let Some(lane_record) = kernel.lanes.get_mut(&lane) {
663 lane_record.pending += 1;
664 }
665 kernel.events.push(Event::CallQueued {
666 job: job_id,
667 lane,
668 cap: cap_id,
669 });
670 Ok(PromiseHandle {
672 agent: self.clone(),
673 id: promise_id,
674 })
675 }
676
677 pub fn run(&self) -> u64 {
679 loop {
680 let batch = {
681 let mut kernel = self.cell.borrow_mut();
682 if kernel.queue.is_empty() {
683 return kernel.round_trips;
684 }
685 match kernel.next_batch() {
686 Ok(batch) => batch,
687 Err(stuck) => {
688 for job_id in stuck {
691 kernel.fail_job(job_id, Error::PipelinedCycle);
692 }
693 continue;
694 }
695 }
696 };
697 self.dispatch(batch);
698 }
699 }
700
701 pub fn round_trips(&self) -> u64 {
703 self.cell.borrow().round_trips
704 }
705
706 pub fn await_promise(&self, promise: &PromiseHandle) -> Result<Value> {
708 loop {
709 {
710 let kernel = self.cell.borrow();
711 let record = kernel
712 .promises
713 .get(&promise.id)
714 .ok_or(Error::UnknownPromise(promise.id.0))?;
715 if record.state.is_settled() {
716 return record.value();
717 }
718 }
719 if self.cell.borrow().queue.is_empty() {
720 return Err(Error::UnresolvablePromise(promise.id.0));
721 }
722 self.run();
723 }
724 }
725
726 pub fn resolve(&self, promise: &PromiseHandle, value: Value) -> Result<()> {
728 let mut kernel = self.cell.borrow_mut();
729 let record = kernel
730 .promises
731 .get_mut(&promise.id)
732 .ok_or(Error::UnknownPromise(promise.id.0))?;
733 record.resolve(value)?;
734 kernel.events.push(Event::PromiseResolved(promise.id));
735 Ok(())
736 }
737
738 pub fn cancel(&self, promise: &PromiseHandle) -> Result<()> {
744 let mut kernel = self.cell.borrow_mut();
745 {
746 let record = kernel
747 .promises
748 .get_mut(&promise.id)
749 .ok_or(Error::UnknownPromise(promise.id.0))?;
750 record.cancel()?;
751 }
752 let queued: Option<u64> = kernel
753 .jobs
754 .iter()
755 .find(|(_, job)| job.promise == promise.id && job.state == JobState::Queued)
756 .map(|(id, _)| *id);
757 if let Some(job_id) = queued {
758 kernel.queue.retain(|id| *id != job_id);
759 let lane = kernel.jobs.get(&job_id).map(|job| job.lane);
760 if let Some(job) = kernel.jobs.get_mut(&job_id) {
761 job.state = JobState::Done;
762 }
763 if let Some(lane) = lane {
764 if let Some(lane_record) = kernel.lanes.get_mut(&lane) {
765 lane_record.complete();
766 }
767 }
768 }
769 Ok(())
770 }
771
772 pub fn take_drops(&self, provider: ProviderId) -> Vec<(u64, CapId)> {
774 self.cell
775 .borrow_mut()
776 .providers
777 .get_mut(&provider)
778 .map(|provider| provider.take_drop_notifications())
779 .unwrap_or_default()
780 }
781
782 pub fn events(&self) -> Vec<Event> {
784 self.cell.borrow().events.clone()
785 }
786
787 pub fn lane(&self, lane: LaneId) -> Result<Lane> {
789 self.cell
790 .borrow()
791 .lanes
792 .get(&lane)
793 .cloned()
794 .ok_or(Error::UnknownLane(lane.0))
795 }
796
797 pub fn channel(&self, channel: ChannelId) -> Result<Channel> {
799 self.cell
800 .borrow()
801 .channels
802 .get(&channel)
803 .cloned()
804 .ok_or(Error::UnknownChannel(channel.0))
805 }
806
807 pub fn cap_attrs(&self, cap: &CapHandle) -> Result<CapAttrs> {
809 self.cell
810 .borrow()
811 .caps
812 .get(&cap.id())
813 .map(|record| record.attrs.clone())
814 .ok_or(Error::UnknownCapability(u128::from_be_bytes(pad128(
815 cap.id(),
816 ))))
817 }
818
819 fn dispatch(&self, batch: Vec<u64>) {
820 let (provider_id, provider) = {
825 let mut kernel = self.cell.borrow_mut();
826 kernel.round_trips += 1;
827 kernel.now_ms = kernel.now_ms.saturating_add(kernel.latency_ms);
828 let Some(first) = batch.first().and_then(|id| kernel.jobs.get(id)) else {
829 return;
830 };
831 let provider_id = kernel
832 .caps
833 .get(&first.cap)
834 .map(|record| record.provider)
835 .unwrap_or(ProviderId(u64::MAX));
836 let lanes: BTreeSet<u64> = batch
837 .iter()
838 .filter_map(|id| kernel.jobs.get(id).map(|job| job.lane.0))
839 .collect();
840 kernel.events.push(Event::BatchDispatched {
841 provider: provider_id,
842 jobs: batch.len(),
843 lanes,
844 });
845 let provider = kernel.providers.remove(&provider_id);
846 (provider_id, provider)
847 };
848 let Some(mut provider) = provider else {
849 let mut kernel = self.cell.borrow_mut();
850 for job_id in batch {
851 kernel.fail_job(
852 job_id,
853 Error::Provider {
854 code: "rpc/provider".to_string(),
855 },
856 );
857 }
858 return;
859 };
860
861 for job_id in &batch {
862 let prepared = {
864 let kernel = self.cell.borrow();
865 let Some(job) = kernel.jobs.get(job_id).cloned() else {
866 continue;
867 };
868 if job.state == JobState::Done {
869 continue;
870 }
871 let mut args = Vec::with_capacity(job.call.args.len());
872 let mut failure = None;
873 for arg in &job.call.args {
874 match arg {
875 Arg::Promise(id) => match kernel.promises.get(id) {
876 Some(record) if record.state.is_settled() => match record.value() {
877 Ok(value) => args.push(Arg::Value(value)),
878 Err(error) => {
879 failure = Some(error);
880 break;
881 }
882 },
883 Some(_) => {
884 failure = Some(Error::UnresolvablePromise(id.0));
885 break;
886 }
887 None => {
888 failure = Some(Error::UnknownPromise(id.0));
889 break;
890 }
891 },
892 other => args.push(other.clone()),
893 }
894 }
895 let record = kernel.caps.get(&job.cap).cloned();
898 let failure = match &record {
899 None => Some(Error::UnknownCapability(0)),
900 Some(record) if record.revoked => {
901 Some(Error::Revoked(u128::from_be_bytes(pad128(record.id))))
902 }
903 Some(_) => failure,
904 };
905 Some((
906 job,
907 args,
908 failure,
909 record.map(|record| record.object).unwrap_or(0),
910 ))
911 };
912 let Some((job, args, failure, object)) = prepared else {
913 continue;
914 };
915
916 let outcome = match failure {
918 Some(error) => Err(error),
919 None => {
920 let call = Call {
921 args,
922 ..job.call.clone()
923 };
924 provider.invoke(object, &call).map(Response::into_value)
925 }
926 };
927
928 let mut kernel = self.cell.borrow_mut();
930 match &outcome {
931 Ok(value) => {
932 if let Some(record) = kernel.promises.get_mut(&job.promise) {
933 let _ = record.resolve(value.clone());
934 }
935 kernel.events.push(Event::PromiseResolved(job.promise));
936 }
937 Err(error) => {
938 if let Some(record) = kernel.promises.get_mut(&job.promise) {
939 let _ = record.reject(error.clone());
940 }
941 kernel.events.push(Event::PromiseRejected {
942 promise: job.promise,
943 code: error.code().to_string(),
944 });
945 }
946 }
947 if let Some(record) = kernel.jobs.get_mut(job_id) {
948 record.state = JobState::Done;
949 }
950 if let Some(lane_record) = kernel.lanes.get_mut(&job.lane) {
951 lane_record.complete();
952 }
953 kernel.events.push(Event::JobCompleted {
954 job: *job_id,
955 lane: job.lane,
956 });
957 }
958
959 self.cell
960 .borrow_mut()
961 .providers
962 .insert(provider_id, provider);
963 }
964}
965
966impl Kernel {
967 fn next_batch(&mut self) -> std::result::Result<Vec<u64>, Vec<u64>> {
970 let Some(head) = self.queue.front().copied() else {
971 return Ok(Vec::new());
972 };
973 let Some(head_job) = self.jobs.get(&head) else {
974 self.queue.pop_front();
975 return Ok(Vec::new());
976 };
977 let Some(provider) = self.caps.get(&head_job.cap).map(|record| record.provider) else {
978 self.queue.pop_front();
980 return Err(vec![head]);
981 };
982 let mut candidates: Vec<u64> = self
983 .queue
984 .iter()
985 .copied()
986 .filter(|id| {
987 self.jobs
988 .get(id)
989 .and_then(|job| self.caps.get(&job.cap))
990 .map(|record| record.provider == provider)
991 .unwrap_or(false)
992 })
993 .collect();
994 let mut ordered: Vec<u64> = Vec::new();
996 let mut pending = candidates.clone();
997 let mut progress = true;
998 while progress && !pending.is_empty() {
999 progress = false;
1000 let mut index = 0;
1001 while index < pending.len() {
1002 let id = pending[index];
1003 let job = self.jobs.get(&id).cloned();
1004 let ready = match &job {
1005 Some(job) => job.deps.iter().all(|dep| {
1006 match self.promises.get(dep) {
1008 Some(record) if record.state.is_settled() => true,
1009 _ => ordered
1010 .iter()
1011 .any(|other| self.jobs.get(other).map(|j| j.promise) == Some(*dep)),
1012 }
1013 }),
1014 None => true,
1015 };
1016 if ready {
1017 ordered.push(id);
1018 pending.remove(index);
1019 progress = true;
1020 } else {
1021 index += 1;
1022 }
1023 }
1024 }
1025 if !pending.is_empty() {
1026 for id in &pending {
1028 self.queue.retain(|queued| queued != id);
1029 }
1030 return Err(pending);
1031 }
1032 candidates.clear();
1033 self.queue.retain(|id| !ordered.contains(id));
1034 Ok(ordered)
1035 }
1036
1037 fn fail_job(&mut self, job_id: u64, error: Error) {
1038 if let Some(job) = self.jobs.get_mut(&job_id) {
1039 job.state = JobState::Done;
1040 let promise = job.promise;
1041 let lane = job.lane;
1042 let code = error.code().to_string();
1043 if let Some(record) = self.promises.get_mut(&promise) {
1044 let _ = record.reject(error);
1045 }
1046 if let Some(lane_record) = self.lanes.get_mut(&lane) {
1047 lane_record.complete();
1048 }
1049 self.events.push(Event::PromiseRejected { promise, code });
1050 self.events.push(Event::JobCompleted { job: job_id, lane });
1051 }
1052 }
1053}
1054
1055fn pad128(id: CapId) -> [u8; 16] {
1056 id.0
1057}
1058
1059#[derive(Clone)]
1061pub struct PromiseHandle {
1062 agent: Agent,
1063 id: PromiseId,
1064}
1065
1066impl PromiseHandle {
1067 pub fn id(&self) -> PromiseId {
1069 self.id
1070 }
1071
1072 pub fn agent(&self) -> &Agent {
1074 &self.agent
1075 }
1076
1077 pub fn value(&self) -> Result<Value> {
1079 self.agent.await_promise(self)
1080 }
1081
1082 pub fn peek(&self) -> Result<Value> {
1084 self.agent
1085 .cell
1086 .borrow()
1087 .promises
1088 .get(&self.id)
1089 .ok_or(Error::UnknownPromise(self.id.0))?
1090 .value()
1091 }
1092
1093 pub fn is_settled(&self) -> bool {
1095 self.agent
1096 .cell
1097 .borrow()
1098 .promises
1099 .get(&self.id)
1100 .map(|record| record.state.is_settled())
1101 .unwrap_or(false)
1102 }
1103}
1104
1105impl std::fmt::Debug for PromiseHandle {
1106 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1107 f.debug_struct("PromiseHandle")
1108 .field("id", &self.id)
1109 .field("settled", &self.is_settled())
1110 .finish()
1111 }
1112}
1113
1114pub fn tool_policy_for(methods: &[&str]) -> ToolPolicy {
1116 ToolPolicy::allow(methods)
1117}
1118
1119pub fn promise_state(agent: &Agent, id: PromiseId) -> Option<PromiseState> {
1121 agent
1122 .cell
1123 .borrow()
1124 .promises
1125 .get(&id)
1126 .map(|record| record.state.clone())
1127}