PKU harness
Concepts

Capabilities

Plugins declare in `requires` what they need from the phone. If the phone can't provide it, the harness hides the plugin and tells the user why.

A phone is different from a computer. Plugins on a phone have no shell and no filesystem that the user can see, and their time in the background is limited. Some campus websites can also only be reached from the campus network.

For this reason, each plugin states what it needs from the phone. A plugin lists these capabilities in PluginDef.requires, and its registry entry has the same requires list. The harness compares the list with what the phone actually offers. If any capability is missing, the plugin is hidden from the agent, its tool calls are refused, and Settings shows the reason.

For example, the finance plugin needs a signed-in campus session and the campus network:

definePlugin({
  id: 'finance',
  // …
  requires: ['campus-session', 'campus-network'],
});

The capabilities

CapabilityMeaningAvailable today
networkGeneral internet accessYes
campus-networkSites that can only be reached from the PKU networkYes (see below)
campus-sessionSigned-in campus requests made through the hostAndroid only
notificationsLocal notificationsYes
backgroundRunning in the background from time to timeYes
cloudA PKU harness Cloud provider is set upWhen a provider is set up
ongoingA persistent notification or foreground serviceAndroid only
phone-controlOperating other apps on the phone (Copilot, through services.phone)Android 12 or later
shellA command-line shellNever on phones
filesystemA filesystemNot offered to plugins

Some of these need a little more explanation.

  • network means internet access with a plain fetch.
  • campus-network is always declared as available in the app. If the phone is not on the campus network, however, the request fails.
  • campus-session means signed-in campus requests made through the host's services.campus. The plugin never sees the credentials. It depends on the native campus-http module, so for now it is only available on Android. iOS will get it once the module is ported to Swift.
  • cloud follows your settings as they change. It is available while you have a Cloud provider set up, and unavailable once you remove it.
  • ongoing corresponds to services.ongoing, which shows a persistent notification or runs a foreground service.
  • shell is never available on phones. A plugin that needs a shell must be a remote plugin.
  • filesystem is not offered to plugins. For a file the user chooses, use services.files.pick.

Rules

  • You must list every capability that the plugin's tools depend on. A plugin that calls services.campus.request requires campus-session. If it also reaches a site that only works on the campus network, it requires campus-network too.
  • A bundled plugin must not require shell or filesystem. Heavy work, such as scraping many pages, text recognition (OCR) or long-running jobs, belongs in a remote plugin.
  • Remote plugins run on a server, so shell is not something the phone has to provide for them. The registry validator rejects requires: ['shell'] in remote entries.
  • You should check that an optional service exists before using it. Without the ongoing capability, services.ongoing is undefined. On a host without cloud support, ctx.cloud is undefined.
  • A plugin that also works without the cloud should declare cloud.optional: true instead of requiring cloud. Check ctx.cloud?.available before using it.

On this page