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