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 attrs.budget.check()?;
340 let attrs = record.attrs.attenuate(attrs)?;
341 let serial = kernel.next_serial;
342 kernel.next_serial += 1;
343 let id = CapId::derive(&kernel.secret, serial, Some(&parent_id));
344 let mut child = CapRecord::new(id, record.provider, record.object, attrs.clone());
345 child.parent = Some(parent_id);
346 kernel.meters.insert(id, BudgetMeter::new(attrs.budget));
347 kernel.caps.insert(id, child);
348 kernel.events.push(Event::CapMinted {
349 cap: id,
350 provider: record.provider,
351 });
352 Ok(CapHandle::new(Rc::clone(&self.control), id))
353 }
354
355 pub fn import(&self, id: CapId) -> CapHandle {
362 CapHandle::borrowed(Rc::clone(&self.control), id)
363 }
364
365 pub fn revoke(&self, cap: &CapHandle) {
367 let mut kernel = self.cell.borrow_mut();
368 let mut doomed = BTreeSet::new();
369 let mut stack = vec![cap.id()];
370 while let Some(id) = stack.pop() {
371 if !doomed.insert(id) {
372 continue;
373 }
374 for (child, record) in &kernel.caps {
375 if record.parent == Some(id) {
376 stack.push(*child);
377 }
378 }
379 }
380 for id in doomed {
381 if let Some(record) = kernel.caps.get_mut(&id) {
382 record.revoked = true;
383 }
384 kernel.events.push(Event::CapRevoked(id));
385 }
386 }
387
388 pub fn create_lane(&self, name: impl Into<String>, budget: Budget) -> Result<LaneId> {
390 budget.check()?;
391 let mut kernel = self.cell.borrow_mut();
392 let id = LaneId(kernel.next_lane);
393 kernel.next_lane += 1;
394 kernel.lanes.insert(id, Lane::new(id, name, budget));
395 kernel.events.push(Event::LaneCreated(id));
396 Ok(id)
397 }
398
399 pub fn attenuate_lane(&self, lane: LaneId, budget: Budget) -> Result<()> {
401 budget.check()?;
402 let mut kernel = self.cell.borrow_mut();
403 let record = kernel
404 .lanes
405 .get_mut(&lane)
406 .ok_or(Error::UnknownLane(lane.0))?;
407 record.attenuate(budget)
408 }
409
410 pub fn destroy_lane(&self, lane: LaneId) -> Result<()> {
416 let mut kernel = self.cell.borrow_mut();
417 {
418 let record = kernel
419 .lanes
420 .get_mut(&lane)
421 .ok_or(Error::UnknownLane(lane.0))?;
422 record.destroy();
423 }
424 let doomed: Vec<u64> = kernel
425 .jobs
426 .iter()
427 .filter(|(_, job)| job.lane == lane && job.state == JobState::Queued)
428 .map(|(id, _)| *id)
429 .collect();
430 kernel.queue.retain(|id| !doomed.contains(id));
431 for job_id in doomed {
432 kernel.fail_job(job_id, Error::UnknownLane(lane.0));
433 }
434 kernel.events.push(Event::LaneDestroyed(lane));
435 Ok(())
436 }
437
438 pub fn create_channel(
440 &self,
441 name: impl Into<String>,
442 direction: Direction,
443 ) -> Result<ChannelId> {
444 let mut kernel = self.cell.borrow_mut();
445 let id = ChannelId(kernel.next_channel);
446 kernel.next_channel += 1;
447 kernel
448 .channels
449 .insert(id, Channel::new(id, name, direction));
450 Ok(id)
451 }
452
453 pub fn subscribe(&self, lane: LaneId, channel: ChannelId) -> Result<()> {
455 let mut kernel = self.cell.borrow_mut();
456 let lane_record = kernel.lanes.get(&lane).ok_or(Error::UnknownLane(lane.0))?;
457 if lane_record.closed {
458 return Err(Error::UnknownLane(lane.0));
459 }
460 let record = kernel
461 .channels
462 .get_mut(&channel)
463 .ok_or(Error::UnknownChannel(channel.0))?;
464 record.subscribers.insert(lane.0);
465 if let Some(lane) = kernel.lanes.get_mut(&lane) {
466 lane.channels.insert(channel.0);
467 }
468 Ok(())
469 }
470
471 pub fn send(
473 &self,
474 lane: LaneId,
475 channel: ChannelId,
476 payload: Value,
477 caps: &[CapHandle],
478 ) -> Result<u64> {
479 let mut kernel = self.cell.borrow_mut();
480 let lane_record = kernel.lanes.get(&lane).ok_or(Error::UnknownLane(lane.0))?;
481 if lane_record.closed {
482 return Err(Error::UnknownLane(lane.0));
483 }
484 let mut cap_ids = Vec::with_capacity(caps.len());
485 for cap in caps {
486 let record = kernel
487 .caps
488 .get(&cap.id())
489 .ok_or(Error::InvalidArgument("unknown capability"))?;
490 if record.revoked {
491 return Err(Error::Revoked(u128::from_be_bytes(pad128(cap.id()))));
492 }
493 cap_ids.push(cap.id());
498 }
499 let record = kernel
500 .channels
501 .get_mut(&channel)
502 .ok_or(Error::UnknownChannel(channel.0))?;
503 let message = record.send(lane, payload, cap_ids.clone())?;
504 kernel.events.push(Event::ChannelSend {
505 channel,
506 sequence: message.sequence,
507 });
508 for id in cap_ids {
509 kernel.transfers += 1;
510 kernel
511 .events
512 .push(Event::CapTransferred { cap: id, channel });
513 }
514 Ok(message.sequence)
515 }
516
517 pub fn recv(&self, channel: ChannelId) -> Result<Option<Message>> {
519 let mut kernel = self.cell.borrow_mut();
520 let record = kernel
521 .channels
522 .get_mut(&channel)
523 .ok_or(Error::UnknownChannel(channel.0))?;
524 let message = record.recv()?;
525 if let Some(message) = &message {
526 kernel.events.push(Event::ChannelRecv {
527 channel,
528 sequence: message.sequence,
529 });
530 }
531 Ok(message)
532 }
533
534 pub fn call(
536 &self,
537 lane: LaneId,
538 cap: &CapHandle,
539 method: &str,
540 args: Vec<Arg>,
541 ) -> Result<PromiseHandle> {
542 let mut kernel = self.cell.borrow_mut();
543 let cap_id = cap.id();
544 let record = kernel
545 .caps
546 .get(&cap_id)
547 .ok_or(Error::UnknownCapability(u128::from_be_bytes(pad128(
548 cap_id,
549 ))))?
550 .clone();
551 if record.revoked {
552 return Err(Error::Revoked(u128::from_be_bytes(pad128(cap_id))));
553 }
554 let (lane_closed, lane_capacity, lane_budget) = {
555 let lane_record = kernel.lanes.get(&lane).ok_or(Error::UnknownLane(lane.0))?;
556 (
557 lane_record.closed,
558 lane_record.has_capacity(),
559 lane_record.budget,
560 )
561 };
562 if lane_closed {
563 return Err(Error::UnknownLane(lane.0));
564 }
565 if !lane_capacity {
566 return Err(Error::BudgetExceeded("lane call"));
567 }
568 if !record.attrs.grants(method) {
569 return Err(Error::MethodNotGranted {
570 method: method.to_string(),
571 });
572 }
573 let provider = kernel
574 .providers
575 .get(&record.provider)
576 .ok_or(Error::InvalidArgument("provider disappeared"))?;
577 if !provider.has_method(method) {
578 return Err(Error::MethodNotGranted {
579 method: method.to_string(),
580 });
581 }
582 if record.attrs.read_only && provider.mutating(method) {
583 return Err(Error::ReadOnly);
584 }
585 if let Some(scope) = &record.attrs.path_scope {
587 for arg in &args {
588 if let Arg::Value(Value::Path(path)) = arg {
589 if !crate::cap::is_path_prefix(scope, path) {
590 return Err(Error::PathNotGranted(path.clone()));
591 }
592 }
593 }
594 }
595 if let Some(policy) = &record.attrs.tool_policy {
597 if !policy.allowed.contains(method) {
598 return Err(Error::ToolPolicy("tool not allowed"));
599 }
600 let bytes: u64 = args.iter().map(Arg::wire_size).sum();
603 if bytes > policy.max_arg_bytes {
604 return Err(Error::ToolPolicy("argument too large"));
605 }
606 }
607 let call_bytes: u64 = args.iter().map(|arg| arg.wire_size()).sum();
608 let effective = record.attrs.budget.intersect(&lane_budget);
609 if call_bytes > effective.max_bytes {
610 return Err(Error::BudgetExceeded("byte"));
611 }
612 let meter = kernel
613 .meters
614 .get_mut(&cap_id)
615 .ok_or(Error::InvalidArgument("capability has no meter"))?;
616 meter.charge(call_bytes)?;
617
618 let promise_id = PromiseId(kernel.next_promise);
619 kernel.next_promise += 1;
620 kernel
621 .promises
622 .insert(promise_id, PromiseRecord::new(promise_id, lane.0));
623 let job_id = kernel.next_job;
624 kernel.next_job += 1;
625 let deps: Vec<PromiseId> = args.iter().filter_map(|arg| arg.promise()).collect();
626 for dep in &deps {
627 if !kernel.promises.contains_key(dep) {
628 return Err(Error::UnknownPromise(dep.0));
629 }
630 if let Some(record) = kernel.promises.get_mut(dep) {
631 record.waiters += 1;
632 }
633 }
634 let call = Call {
635 method: method.to_string(),
636 args,
637 path_scope: record.attrs.path_scope.clone(),
638 redact: record.attrs.redact,
639 read_only: record.attrs.read_only,
640 tool_allows_process: record
641 .attrs
642 .tool_policy
643 .as_ref()
644 .map(|policy| policy.allow_process)
645 .unwrap_or(false),
646 budget: effective,
647 };
648 let job = Job {
649 id: job_id,
650 lane,
651 cap: cap_id,
652 call,
653 deps,
654 promise: promise_id,
655 state: JobState::Queued,
656 };
657 kernel.jobs.insert(job_id, job);
658 kernel.queue.push_back(job_id);
659 if let Some(lane_record) = kernel.lanes.get_mut(&lane) {
660 lane_record.pending += 1;
661 }
662 kernel.events.push(Event::CallQueued {
663 job: job_id,
664 lane,
665 cap: cap_id,
666 });
667 Ok(PromiseHandle {
669 agent: self.clone(),
670 id: promise_id,
671 })
672 }
673
674 pub fn run(&self) -> u64 {
676 loop {
677 let batch = {
678 let mut kernel = self.cell.borrow_mut();
679 if kernel.queue.is_empty() {
680 return kernel.round_trips;
681 }
682 match kernel.next_batch() {
683 Ok(batch) => batch,
684 Err(stuck) => {
685 for job_id in stuck {
688 kernel.fail_job(job_id, Error::PipelinedCycle);
689 }
690 continue;
691 }
692 }
693 };
694 self.dispatch(batch);
695 }
696 }
697
698 pub fn round_trips(&self) -> u64 {
700 self.cell.borrow().round_trips
701 }
702
703 pub fn await_promise(&self, promise: &PromiseHandle) -> Result<Value> {
705 loop {
706 {
707 let kernel = self.cell.borrow();
708 let record = kernel
709 .promises
710 .get(&promise.id)
711 .ok_or(Error::UnknownPromise(promise.id.0))?;
712 if record.state.is_settled() {
713 return record.value();
714 }
715 }
716 if self.cell.borrow().queue.is_empty() {
717 return Err(Error::UnresolvablePromise(promise.id.0));
718 }
719 self.run();
720 }
721 }
722
723 pub fn resolve(&self, promise: &PromiseHandle, value: Value) -> Result<()> {
725 let mut kernel = self.cell.borrow_mut();
726 let record = kernel
727 .promises
728 .get_mut(&promise.id)
729 .ok_or(Error::UnknownPromise(promise.id.0))?;
730 record.resolve(value)?;
731 kernel.events.push(Event::PromiseResolved(promise.id));
732 Ok(())
733 }
734
735 pub fn cancel(&self, promise: &PromiseHandle) -> Result<()> {
741 let mut kernel = self.cell.borrow_mut();
742 {
743 let record = kernel
744 .promises
745 .get_mut(&promise.id)
746 .ok_or(Error::UnknownPromise(promise.id.0))?;
747 record.cancel()?;
748 }
749 let queued: Option<u64> = kernel
750 .jobs
751 .iter()
752 .find(|(_, job)| job.promise == promise.id && job.state == JobState::Queued)
753 .map(|(id, _)| *id);
754 if let Some(job_id) = queued {
755 kernel.queue.retain(|id| *id != job_id);
756 let lane = kernel.jobs.get(&job_id).map(|job| job.lane);
757 if let Some(job) = kernel.jobs.get_mut(&job_id) {
758 job.state = JobState::Done;
759 }
760 if let Some(lane) = lane {
761 if let Some(lane_record) = kernel.lanes.get_mut(&lane) {
762 lane_record.complete();
763 }
764 }
765 }
766 Ok(())
767 }
768
769 pub fn take_drops(&self, provider: ProviderId) -> Vec<(u64, CapId)> {
771 self.cell
772 .borrow_mut()
773 .providers
774 .get_mut(&provider)
775 .map(|provider| provider.take_drop_notifications())
776 .unwrap_or_default()
777 }
778
779 pub fn events(&self) -> Vec<Event> {
781 self.cell.borrow().events.clone()
782 }
783
784 pub fn lane(&self, lane: LaneId) -> Result<Lane> {
786 self.cell
787 .borrow()
788 .lanes
789 .get(&lane)
790 .cloned()
791 .ok_or(Error::UnknownLane(lane.0))
792 }
793
794 pub fn channel(&self, channel: ChannelId) -> Result<Channel> {
796 self.cell
797 .borrow()
798 .channels
799 .get(&channel)
800 .cloned()
801 .ok_or(Error::UnknownChannel(channel.0))
802 }
803
804 pub fn cap_attrs(&self, cap: &CapHandle) -> Result<CapAttrs> {
806 self.cell
807 .borrow()
808 .caps
809 .get(&cap.id())
810 .map(|record| record.attrs.clone())
811 .ok_or(Error::UnknownCapability(u128::from_be_bytes(pad128(
812 cap.id(),
813 ))))
814 }
815
816 fn dispatch(&self, batch: Vec<u64>) {
817 let (provider_id, provider) = {
822 let mut kernel = self.cell.borrow_mut();
823 kernel.round_trips += 1;
824 kernel.now_ms = kernel.now_ms.saturating_add(kernel.latency_ms);
825 let Some(first) = batch.first().and_then(|id| kernel.jobs.get(id)) else {
826 return;
827 };
828 let provider_id = kernel
829 .caps
830 .get(&first.cap)
831 .map(|record| record.provider)
832 .unwrap_or(ProviderId(u64::MAX));
833 let lanes: BTreeSet<u64> = batch
834 .iter()
835 .filter_map(|id| kernel.jobs.get(id).map(|job| job.lane.0))
836 .collect();
837 kernel.events.push(Event::BatchDispatched {
838 provider: provider_id,
839 jobs: batch.len(),
840 lanes,
841 });
842 let provider = kernel.providers.remove(&provider_id);
843 (provider_id, provider)
844 };
845 let Some(mut provider) = provider else {
846 let mut kernel = self.cell.borrow_mut();
847 for job_id in batch {
848 kernel.fail_job(
849 job_id,
850 Error::Provider {
851 code: "rpc/provider".to_string(),
852 },
853 );
854 }
855 return;
856 };
857
858 for job_id in &batch {
859 let prepared = {
861 let kernel = self.cell.borrow();
862 let Some(job) = kernel.jobs.get(job_id).cloned() else {
863 continue;
864 };
865 if job.state == JobState::Done {
866 continue;
867 }
868 let mut args = Vec::with_capacity(job.call.args.len());
869 let mut failure = None;
870 for arg in &job.call.args {
871 match arg {
872 Arg::Promise(id) => match kernel.promises.get(id) {
873 Some(record) if record.state.is_settled() => match record.value() {
874 Ok(value) => args.push(Arg::Value(value)),
875 Err(error) => {
876 failure = Some(error);
877 break;
878 }
879 },
880 Some(_) => {
881 failure = Some(Error::UnresolvablePromise(id.0));
882 break;
883 }
884 None => {
885 failure = Some(Error::UnknownPromise(id.0));
886 break;
887 }
888 },
889 other => args.push(other.clone()),
890 }
891 }
892 let record = kernel.caps.get(&job.cap).cloned();
895 let failure = match &record {
896 None => Some(Error::UnknownCapability(0)),
897 Some(record) if record.revoked => {
898 Some(Error::Revoked(u128::from_be_bytes(pad128(record.id))))
899 }
900 Some(_) => failure,
901 };
902 Some((
903 job,
904 args,
905 failure,
906 record.map(|record| record.object).unwrap_or(0),
907 ))
908 };
909 let Some((job, args, failure, object)) = prepared else {
910 continue;
911 };
912
913 let outcome = match failure {
915 Some(error) => Err(error),
916 None => {
917 let call = Call {
918 args,
919 ..job.call.clone()
920 };
921 provider.invoke(object, &call).map(Response::into_value)
922 }
923 };
924
925 let mut kernel = self.cell.borrow_mut();
927 match &outcome {
928 Ok(value) => {
929 if let Some(record) = kernel.promises.get_mut(&job.promise) {
930 let _ = record.resolve(value.clone());
931 }
932 kernel.events.push(Event::PromiseResolved(job.promise));
933 }
934 Err(error) => {
935 if let Some(record) = kernel.promises.get_mut(&job.promise) {
936 let _ = record.reject(error.clone());
937 }
938 kernel.events.push(Event::PromiseRejected {
939 promise: job.promise,
940 code: error.code().to_string(),
941 });
942 }
943 }
944 if let Some(record) = kernel.jobs.get_mut(job_id) {
945 record.state = JobState::Done;
946 }
947 if let Some(lane_record) = kernel.lanes.get_mut(&job.lane) {
948 lane_record.complete();
949 }
950 kernel.events.push(Event::JobCompleted {
951 job: *job_id,
952 lane: job.lane,
953 });
954 }
955
956 self.cell
957 .borrow_mut()
958 .providers
959 .insert(provider_id, provider);
960 }
961}
962
963impl Kernel {
964 fn next_batch(&mut self) -> std::result::Result<Vec<u64>, Vec<u64>> {
967 let Some(head) = self.queue.front().copied() else {
968 return Ok(Vec::new());
969 };
970 let Some(head_job) = self.jobs.get(&head) else {
971 self.queue.pop_front();
972 return Ok(Vec::new());
973 };
974 let Some(provider) = self.caps.get(&head_job.cap).map(|record| record.provider) else {
975 self.queue.pop_front();
977 return Err(vec![head]);
978 };
979 let mut candidates: Vec<u64> = self
980 .queue
981 .iter()
982 .copied()
983 .filter(|id| {
984 self.jobs
985 .get(id)
986 .and_then(|job| self.caps.get(&job.cap))
987 .map(|record| record.provider == provider)
988 .unwrap_or(false)
989 })
990 .collect();
991 let mut ordered: Vec<u64> = Vec::new();
993 let mut pending = candidates.clone();
994 let mut progress = true;
995 while progress && !pending.is_empty() {
996 progress = false;
997 let mut index = 0;
998 while index < pending.len() {
999 let id = pending[index];
1000 let job = self.jobs.get(&id).cloned();
1001 let ready = match &job {
1002 Some(job) => job.deps.iter().all(|dep| {
1003 match self.promises.get(dep) {
1005 Some(record) if record.state.is_settled() => true,
1006 _ => ordered
1007 .iter()
1008 .any(|other| self.jobs.get(other).map(|j| j.promise) == Some(*dep)),
1009 }
1010 }),
1011 None => true,
1012 };
1013 if ready {
1014 ordered.push(id);
1015 pending.remove(index);
1016 progress = true;
1017 } else {
1018 index += 1;
1019 }
1020 }
1021 }
1022 if !pending.is_empty() {
1023 for id in &pending {
1025 self.queue.retain(|queued| queued != id);
1026 }
1027 return Err(pending);
1028 }
1029 candidates.clear();
1030 self.queue.retain(|id| !ordered.contains(id));
1031 Ok(ordered)
1032 }
1033
1034 fn fail_job(&mut self, job_id: u64, error: Error) {
1035 if let Some(job) = self.jobs.get_mut(&job_id) {
1036 job.state = JobState::Done;
1037 let promise = job.promise;
1038 let lane = job.lane;
1039 let code = error.code().to_string();
1040 if let Some(record) = self.promises.get_mut(&promise) {
1041 let _ = record.reject(error);
1042 }
1043 if let Some(lane_record) = self.lanes.get_mut(&lane) {
1044 lane_record.complete();
1045 }
1046 self.events.push(Event::PromiseRejected { promise, code });
1047 self.events.push(Event::JobCompleted { job: job_id, lane });
1048 }
1049 }
1050}
1051
1052fn pad128(id: CapId) -> [u8; 16] {
1053 id.0
1054}
1055
1056#[derive(Clone)]
1058pub struct PromiseHandle {
1059 agent: Agent,
1060 id: PromiseId,
1061}
1062
1063impl PromiseHandle {
1064 pub fn id(&self) -> PromiseId {
1066 self.id
1067 }
1068
1069 pub fn agent(&self) -> &Agent {
1071 &self.agent
1072 }
1073
1074 pub fn value(&self) -> Result<Value> {
1076 self.agent.await_promise(self)
1077 }
1078
1079 pub fn peek(&self) -> Result<Value> {
1081 self.agent
1082 .cell
1083 .borrow()
1084 .promises
1085 .get(&self.id)
1086 .ok_or(Error::UnknownPromise(self.id.0))?
1087 .value()
1088 }
1089
1090 pub fn is_settled(&self) -> bool {
1092 self.agent
1093 .cell
1094 .borrow()
1095 .promises
1096 .get(&self.id)
1097 .map(|record| record.state.is_settled())
1098 .unwrap_or(false)
1099 }
1100}
1101
1102impl std::fmt::Debug for PromiseHandle {
1103 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1104 f.debug_struct("PromiseHandle")
1105 .field("id", &self.id)
1106 .field("settled", &self.is_settled())
1107 .finish()
1108 }
1109}
1110
1111pub fn tool_policy_for(methods: &[&str]) -> ToolPolicy {
1113 ToolPolicy::allow(methods)
1114}
1115
1116pub fn promise_state(agent: &Agent, id: PromiseId) -> Option<PromiseState> {
1118 agent
1119 .cell
1120 .borrow()
1121 .promises
1122 .get(&id)
1123 .map(|record| record.state.clone())
1124}