@pasko70/pibo 1.16.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/dist/agent-runtime/auth.js +28 -0
  2. package/dist/agent-runtime/capabilities.js +221 -0
  3. package/dist/agent-runtime/context-build.js +313 -0
  4. package/dist/agent-runtime/contract.js +45 -0
  5. package/dist/agent-runtime/errors.js +57 -0
  6. package/dist/agent-runtime/events.js +1 -0
  7. package/dist/agent-runtime/history.js +1 -0
  8. package/dist/agent-runtime/profile-validation.js +109 -0
  9. package/dist/agent-runtime/registry.js +608 -0
  10. package/dist/agent-runtime/resource-files.js +87 -0
  11. package/dist/agent-runtime/resource-service.js +635 -0
  12. package/dist/agent-runtime/resources.js +1 -0
  13. package/dist/agent-runtime/routed-session.js +931 -0
  14. package/dist/agent-runtime/testing/contract.js +51 -0
  15. package/dist/agent-runtime/testing/fake-adapter.js +192 -0
  16. package/dist/agent-runtime/types.js +3 -0
  17. package/dist/agent-runtimes/codex-native/adapter.js +905 -0
  18. package/dist/agent-runtimes/codex-native/auth.js +476 -0
  19. package/dist/agent-runtimes/codex-native/client.js +734 -0
  20. package/dist/agent-runtimes/codex-native/config.js +152 -0
  21. package/dist/agent-runtimes/codex-native/history.js +283 -0
  22. package/dist/agent-runtimes/codex-native/mcp-stdio-launcher.js +89 -0
  23. package/dist/agent-runtimes/codex-native/models.js +581 -0
  24. package/dist/agent-runtimes/codex-native/process.js +459 -0
  25. package/dist/agent-runtimes/codex-native/protocol-types.js +1 -0
  26. package/dist/agent-runtimes/codex-native/protocol-version.js +7 -0
  27. package/dist/agent-runtimes/codex-native/redaction.js +31 -0
  28. package/dist/agent-runtimes/codex-native/requests.js +378 -0
  29. package/dist/agent-runtimes/codex-native/resource-delivery.js +445 -0
  30. package/dist/agent-runtimes/codex-native/thread.js +388 -0
  31. package/dist/agent-runtimes/codex-native/turn.js +849 -0
  32. package/dist/agent-runtimes/pi/adapter.js +653 -0
  33. package/dist/agent-runtimes/pi/auth.js +455 -0
  34. package/dist/agent-runtimes/pi/history.js +640 -0
  35. package/dist/agent-runtimes/pi/model-catalog.js +87 -0
  36. package/dist/agent-runtimes/pi/routed-session.js +1464 -0
  37. package/dist/agent-runtimes/pi/runtime.js +534 -0
  38. package/dist/agent-runtimes/pi/tool-compiler.js +69 -0
  39. package/dist/apps/chat/agent-profiles.js +40 -23
  40. package/dist/apps/chat/agent-store.js +111 -64
  41. package/dist/apps/chat/chat-api-routes.js +1 -1
  42. package/dist/apps/chat/chat-request-normalizers.js +47 -0
  43. package/dist/apps/chat/data/chat-data-mappers.js +25 -9
  44. package/dist/apps/chat/data/history-query-service.js +108 -0
  45. package/dist/apps/chat/data/session-query-service.js +24 -3
  46. package/dist/apps/chat/data/timeline-query-service.js +3 -3
  47. package/dist/apps/chat/model-catalog.js +1 -55
  48. package/dist/apps/chat/provider-auth-actions.js +171 -23
  49. package/dist/apps/chat/stream.js +12 -0
  50. package/dist/apps/chat/trace-v2.js +1 -0
  51. package/dist/apps/chat/trace.js +126 -415
  52. package/dist/apps/chat/web-app.js +582 -157
  53. package/dist/apps/chat-ui/assets/{dist-QXwINWYY.js → dist-9v2ZXT6V.js} +1 -1
  54. package/dist/apps/chat-ui/assets/{dist-CvZNkkOi.js → dist-B1LVAytl.js} +1 -1
  55. package/dist/apps/chat-ui/assets/{dist-_SP-MjLq.js → dist-C6LPDFXU.js} +1 -1
  56. package/dist/apps/chat-ui/assets/{dist-Bad4Yz4P.js → dist-DVtXxfHc.js} +1 -1
  57. package/dist/apps/chat-ui/assets/{dist-xy-zomwl.js → dist-DW4Qrfbd.js} +1 -1
  58. package/dist/apps/chat-ui/assets/{dist-DI4i80O2.js → dist-DmbsHdMC.js} +1 -1
  59. package/dist/apps/chat-ui/assets/{dist-D17yAUqp.js → dist-DyvwuSFO.js} +1 -1
  60. package/dist/apps/chat-ui/assets/{dist-Bc3Vbgjh.js → dist-I26VB0QO.js} +1 -1
  61. package/dist/apps/chat-ui/assets/{dist-BzqH7w58.js → dist-RtHbJRPV.js} +1 -1
  62. package/dist/apps/chat-ui/assets/{dist-CMDJ-WZm.js → dist-sZgJkWZb.js} +1 -1
  63. package/dist/apps/chat-ui/assets/index-BPbNvcZe.css +1 -0
  64. package/dist/apps/chat-ui/assets/index-CIOf2uL2.js +237 -0
  65. package/dist/apps/chat-ui/index.html +2 -2
  66. package/dist/apps/chat-vscode-web/assets/index-1ivRyjFs.js +41 -0
  67. package/dist/apps/chat-vscode-web/index.html +1 -1
  68. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  69. package/dist/apps/vscode-artifacts/pibo-vscode-ext-2.0.0.vsix +0 -0
  70. package/dist/auth/login-actions.js +5 -251
  71. package/dist/cli-session/localSessionSource.js +8 -1
  72. package/dist/core/context-build.js +124 -20
  73. package/dist/core/default-profile.js +8 -0
  74. package/dist/core/profiles.js +30 -3
  75. package/dist/core/routed-session.js +5 -1446
  76. package/dist/core/runtime.js +5 -561
  77. package/dist/core/session-router.js +637 -83
  78. package/dist/data/cli.js +20 -3
  79. package/dist/data/schema.js +104 -1
  80. package/dist/data/session-store.js +24 -1
  81. package/dist/debug/events.js +25 -10
  82. package/dist/debug/failures.js +23 -3
  83. package/dist/debug/index.js +24 -6
  84. package/dist/debug/messages.js +87 -7
  85. package/dist/debug/persisted-payloads.js +31 -0
  86. package/dist/debug/pty.js +7 -6
  87. package/dist/debug/runtime-binding.js +29 -0
  88. package/dist/debug/session.js +137 -0
  89. package/dist/debug/summary.js +12 -0
  90. package/dist/debug/telemetry.js +28 -0
  91. package/dist/debug/tools.js +12 -2
  92. package/dist/debug/trace.js +154 -76
  93. package/dist/gateway/server.js +87 -2
  94. package/dist/gateway/tool.js +5 -5
  95. package/dist/index.js +21 -2
  96. package/dist/loops/tools.js +13 -12
  97. package/dist/mcp/agent-context.js +13 -4
  98. package/dist/mcp/client.js +10 -6
  99. package/dist/mcp/config.js +5 -2
  100. package/dist/mcp/runtime-session.js +166 -0
  101. package/dist/plugins/builtin.js +191 -53
  102. package/dist/plugins/codex-native.js +29 -0
  103. package/dist/plugins/registry.js +66 -2
  104. package/dist/runs/tools.js +26 -25
  105. package/dist/session-ui/terminalRows.js +2 -2
  106. package/dist/sessions/pibo-data-store.js +125 -16
  107. package/dist/sessions/runtime-binding.js +107 -0
  108. package/dist/sessions/sqlite-store.js +239 -18
  109. package/dist/sessions/store.js +86 -7
  110. package/dist/shared/trace-engine.js +18 -9
  111. package/dist/shared/trace-event-projection.js +29 -11
  112. package/dist/shared/{trace-transcript.js → trace-history.js} +193 -195
  113. package/dist/shared/trace-order.js +9 -4
  114. package/dist/shared/trace-page-merge.js +1 -1
  115. package/dist/signals/projector.js +20 -2
  116. package/dist/signals/registry.js +11 -0
  117. package/dist/subagents/tool.js +8 -6
  118. package/dist/tools/codex-browser.js +20 -19
  119. package/dist/tools/codex-compat.js +10 -9
  120. package/dist/tools/codex-image-generation.js +8 -6
  121. package/dist/tools/contract.js +45 -0
  122. package/dist/tools/credential-registry.js +182 -0
  123. package/dist/tools/mcp-bridge.js +511 -0
  124. package/dist/tools/payload-writer.js +17 -0
  125. package/dist/tools/runtime/tool.js +10 -9
  126. package/dist/tools/schema.js +9 -0
  127. package/dist/tools/session-service.js +193 -0
  128. package/dist/tools/session-tool-set.js +85 -0
  129. package/dist/web-annotations/tools.js +17 -16
  130. package/docs/README.md +11 -0
  131. package/package.json +3 -2
  132. package/skills/builtin/pibo-agent-runtime-adapter/SKILL.md +183 -0
  133. package/skills/builtin/pibo-agent-runtime-adapter/evals/README.md +10 -0
  134. package/skills/builtin/pibo-agent-runtime-adapter/evals/evals.json +45 -0
  135. package/skills/builtin/pibo-agent-runtime-adapter/evals/fixtures/orion-full-harness.md +60 -0
  136. package/skills/builtin/pibo-agent-runtime-adapter/evals/fixtures/relay-partial-harness.md +52 -0
  137. package/skills/builtin/pibo-agent-runtime-adapter/references/capabilities-and-designer.md +194 -0
  138. package/skills/builtin/pibo-agent-runtime-adapter/references/history-debug-and-security.md +213 -0
  139. package/skills/builtin/pibo-agent-runtime-adapter/references/interfaces-and-registration.md +214 -0
  140. package/skills/builtin/pibo-agent-runtime-adapter/references/lifecycle-bindings-and-events.md +193 -0
  141. package/skills/builtin/pibo-agent-runtime-adapter/references/portable-delivery-and-native-behavior.md +226 -0
  142. package/skills/builtin/pibo-agent-runtime-adapter/references/testing-migration-and-validation.md +256 -0
  143. package/dist/apps/chat-ui/assets/index-C45B0rw7.js +0 -237
  144. package/dist/apps/chat-ui/assets/index-E0RmuCkY.css +0 -1
  145. package/dist/apps/chat-vscode-web/assets/index-D-tSsXLG.js +0 -41
  146. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.16.5.vsix +0 -0
@@ -0,0 +1,166 @@
1
+ import { createHash } from "node:crypto";
2
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
3
+ import { getDefaultEnvironment, StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
4
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
5
+ import { filterTools, isHttpServer, } from "./config.js";
6
+ const SECRET_KEY_RE = /(api[_-]?key|authorization|bearer|cookie|credential|oauth|password|secret|token)/i;
7
+ const ENV_REFERENCE_RE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
8
+ function resolveEnvironmentString(value, environment) {
9
+ const missing = new Set();
10
+ const resolved = value.replace(ENV_REFERENCE_RE, (_match, name) => {
11
+ const replacement = environment[name];
12
+ if (replacement === undefined) {
13
+ missing.add(name);
14
+ return "";
15
+ }
16
+ return replacement;
17
+ });
18
+ if (missing.size > 0)
19
+ throw new Error(`Missing environment variables: ${[...missing].sort().join(", ")}`);
20
+ return resolved;
21
+ }
22
+ function generatedSecretName(serverName, path, value) {
23
+ const readable = [serverName, ...path]
24
+ .join("_")
25
+ .toUpperCase()
26
+ .replace(/[^A-Z0-9_]+/g, "_")
27
+ .replace(/^_+|_+$/g, "")
28
+ .slice(0, 72);
29
+ const hash = createHash("sha256").update(`${serverName}\0${path.join(".")}\0${value}`).digest("hex").slice(0, 12).toUpperCase();
30
+ return `PIBO_RUNTIME_MCP_${readable || "VALUE"}_${hash}`;
31
+ }
32
+ function urlLooksSensitive(value) {
33
+ try {
34
+ const url = new URL(value);
35
+ if (url.username || url.password)
36
+ return true;
37
+ for (const key of url.searchParams.keys()) {
38
+ if (SECRET_KEY_RE.test(key))
39
+ return true;
40
+ }
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ return false;
46
+ }
47
+ function scopeConfigValue(serverName, value, path, environment, secretEnvironment, forceSecret = false) {
48
+ if (typeof value === "string") {
49
+ const hasReference = ENV_REFERENCE_RE.test(value);
50
+ ENV_REFERENCE_RE.lastIndex = 0;
51
+ const secret = forceSecret || hasReference || SECRET_KEY_RE.test(path.at(-1) ?? "") || (path.at(-1) === "url" && urlLooksSensitive(value));
52
+ if (!secret)
53
+ return { materialized: value, resolved: value };
54
+ const resolved = resolveEnvironmentString(value, environment);
55
+ const environmentName = generatedSecretName(serverName, path, value);
56
+ secretEnvironment[environmentName] = resolved;
57
+ return { materialized: `\${${environmentName}}`, resolved };
58
+ }
59
+ if (Array.isArray(value)) {
60
+ const materialized = [];
61
+ const resolved = [];
62
+ for (const [index, item] of value.entries()) {
63
+ const scoped = scopeConfigValue(serverName, item, [...path, String(index)], environment, secretEnvironment, forceSecret);
64
+ materialized.push(scoped.materialized);
65
+ resolved.push(scoped.resolved);
66
+ }
67
+ return { materialized, resolved };
68
+ }
69
+ if (value && typeof value === "object") {
70
+ const materialized = {};
71
+ const resolved = {};
72
+ for (const [key, item] of Object.entries(value)) {
73
+ const scoped = scopeConfigValue(serverName, item, [...path, key], environment, secretEnvironment, forceSecret || path.at(-1) === "env" || path.at(-1) === "headers" || path.at(-1) === "args");
74
+ materialized[key] = scoped.materialized;
75
+ resolved[key] = scoped.resolved;
76
+ }
77
+ return { materialized, resolved };
78
+ }
79
+ return { materialized: value, resolved: value };
80
+ }
81
+ export function scopePiboMcpServerConfig(serverName, config, environment) {
82
+ const secretEnvironment = {};
83
+ const scoped = scopeConfigValue(serverName, config, [], environment, secretEnvironment);
84
+ return {
85
+ materialized: scoped.materialized,
86
+ resolved: scoped.resolved,
87
+ secretEnvironment,
88
+ secretEnvironmentKeys: Object.keys(secretEnvironment).sort(),
89
+ };
90
+ }
91
+ export function redactMcpRuntimeError(error, secretValues = []) {
92
+ let message = error instanceof Error ? error.message : String(error);
93
+ for (const value of secretValues) {
94
+ if (value)
95
+ message = message.split(value).join("[REDACTED]");
96
+ }
97
+ return message.replace(/Bearer\s+\S+/gi, "Bearer [REDACTED]");
98
+ }
99
+ export async function verifyPiboMcpServer(serverName, config, options) {
100
+ const client = new Client({ name: "pibo-runtime-resource-verifier", version: "1.0.0" }, { capabilities: {} });
101
+ let transport;
102
+ if (isHttpServer(config)) {
103
+ transport = new StreamableHTTPClientTransport(new URL(config.url), {
104
+ requestInit: { headers: config.headers },
105
+ });
106
+ }
107
+ else {
108
+ const env = {
109
+ ...getDefaultEnvironment(),
110
+ ...(config.env ?? {}),
111
+ };
112
+ transport = new StdioClientTransport({
113
+ command: config.command,
114
+ args: config.args,
115
+ env,
116
+ cwd: config.cwd,
117
+ stderr: "pipe",
118
+ });
119
+ }
120
+ const signal = AbortSignal.timeout(options.timeoutMs);
121
+ try {
122
+ await client.connect(transport, { signal, timeout: options.timeoutMs, maxTotalTimeout: options.timeoutMs });
123
+ const capabilities = client.getServerCapabilities();
124
+ const listedTools = capabilities?.tools
125
+ ? (await client.listTools(undefined, { signal, timeout: options.timeoutMs, maxTotalTimeout: options.timeoutMs })).tools
126
+ : [];
127
+ const tools = filterTools(listedTools.map((tool) => ({
128
+ name: tool.name,
129
+ ...(tool.description ? { description: tool.description } : {}),
130
+ })), config);
131
+ let resources = [];
132
+ let resourceTemplates = [];
133
+ if (capabilities?.resources) {
134
+ const listed = await client.listResources(undefined, { signal, timeout: options.timeoutMs, maxTotalTimeout: options.timeoutMs });
135
+ resources = listed.resources.map((resource) => ({
136
+ uri: resource.uri,
137
+ ...(resource.name ? { name: resource.name } : {}),
138
+ ...(resource.description ? { description: resource.description } : {}),
139
+ ...(resource.mimeType ? { mimeType: resource.mimeType } : {}),
140
+ }));
141
+ const templates = await client.listResourceTemplates(undefined, { signal, timeout: options.timeoutMs, maxTotalTimeout: options.timeoutMs });
142
+ resourceTemplates = templates.resourceTemplates.map((template) => ({
143
+ uriTemplate: template.uriTemplate,
144
+ ...(template.name ? { name: template.name } : {}),
145
+ ...(template.description ? { description: template.description } : {}),
146
+ ...(template.mimeType ? { mimeType: template.mimeType } : {}),
147
+ }));
148
+ }
149
+ const version = client.getServerVersion();
150
+ return {
151
+ status: "connected",
152
+ ...(version?.name ? { serverName: version.name } : {}),
153
+ ...(version?.version ? { serverVersion: version.version } : {}),
154
+ ...(client.getInstructions() ? { instructions: client.getInstructions() } : {}),
155
+ tools,
156
+ resources,
157
+ resourceTemplates,
158
+ };
159
+ }
160
+ catch (error) {
161
+ throw new Error(`MCP server "${serverName}" verification failed: ${redactMcpRuntimeError(error)}`);
162
+ }
163
+ finally {
164
+ await client.close().catch(async () => transport.close().catch(() => { }));
165
+ }
166
+ }
@@ -2,32 +2,25 @@ import { dirname, resolve } from "node:path";
2
2
  import { fileURLToPath } from "node:url";
3
3
  import { createPiboGatewayToolProfiles } from "../gateway/tool.js";
4
4
  import { InitialSessionContextBuilder } from "../core/profiles.js";
5
+ import { createDefaultPiboProfile, DEFAULT_PIBO_PROFILE_NAME } from "../core/default-profile.js";
5
6
  import { parsePiboThinkingLevel } from "../core/thinking.js";
6
7
  import { createWebSearchToolProfile } from "../tools/web-search.js";
7
8
  import { CODEX_BROWSER_TOOL_NAMES, createCodexBrowserToolProfiles } from "../tools/codex-browser.js";
8
9
  import { createRuntimeToolProfile } from "../tools/runtime/tool.js";
9
- import { completeLogin, getLoginStatus, removeLogin, setApiKey, startLogin } from "../auth/login-actions.js";
10
10
  import { loadModelCatalog } from "../apps/chat/model-catalog.js";
11
11
  import { piboCodexCompatPlugin } from "./codex-compat.js";
12
+ import { piboCodexNativePlugin } from "./codex-native.js";
12
13
  import { addPiboNativeToolingContext, registerPiboNativeTooling } from "./native-tooling.js";
13
14
  import { piboWebAnnotationsPlugin } from "./web-annotations.js";
14
15
  import { definePiboPlugin, PiboPluginRegistry } from "./registry.js";
15
- export const DEFAULT_PIBO_PROFILE_NAME = "base";
16
+ import { PI_AGENT_RUNTIME_DRIVER } from "../agent-runtimes/pi/adapter.js";
17
+ export { createDefaultPiboProfile, DEFAULT_PIBO_PROFILE_NAME } from "../core/default-profile.js";
18
+ export { CODEX_NATIVE_PROFILE_NAME, CODEX_NATIVE_RUNTIME_INSTANCE_ID, piboCodexNativePlugin, } from "./codex-native.js";
16
19
  const GATEWAY_PROFILE_TOOLS = ["pibo_gateway_send"];
17
20
  const PIBO_PACKAGE_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../..");
18
21
  function builtinSkillPath(name) {
19
22
  return resolve(PIBO_PACKAGE_ROOT, "skills", "builtin", name, "SKILL.md");
20
23
  }
21
- const LOGIN_PROVIDERS = [
22
- { id: "openai-codex", name: "OpenAI (ChatGPT Plus/Pro)", authMethods: ["device_code"] },
23
- { id: "openai", name: "OpenAI API", authMethods: ["api_key"] },
24
- { id: "anthropic", name: "Anthropic", authMethods: ["api_key"] },
25
- { id: "qwen-token-plan", name: "Qwen Token Plan", authMethods: ["api_key"] },
26
- { id: "kimi-coding", name: "Kimi for Coding", authMethods: ["api_key"] },
27
- { id: "google", name: "Google Gemini", authMethods: ["api_key"] },
28
- { id: "groq", name: "Groq", authMethods: ["api_key"] },
29
- { id: "ollama", name: "Ollama", authMethods: ["api_key"] },
30
- ];
31
24
  function getObjectParams(event) {
32
25
  const params = "params" in event ? event.params : undefined;
33
26
  if (!params || typeof params !== "object" || Array.isArray(params))
@@ -75,12 +68,35 @@ function getThinkingParams(event) {
75
68
  throw new Error("thinking requires params.level to be a string");
76
69
  return { level: parsePiboThinkingLevel(raw.level) };
77
70
  }
71
+ function requireApprovalResponseParams(event) {
72
+ const params = getObjectParams(event);
73
+ if (!params || typeof params.requestId !== "string" || !params.requestId.trim()) {
74
+ throw new Error("runtime.approval.respond requires params.requestId");
75
+ }
76
+ if (typeof params.decision !== "string" || !params.decision.trim()) {
77
+ throw new Error("runtime.approval.respond requires params.decision");
78
+ }
79
+ return { requestId: params.requestId, decision: params.decision };
80
+ }
81
+ function requireUserInputResponseParams(event) {
82
+ const params = getObjectParams(event);
83
+ if (!params || typeof params.requestId !== "string" || !params.requestId.trim()) {
84
+ throw new Error("runtime.user_input.respond requires params.requestId");
85
+ }
86
+ if (!params.answers || typeof params.answers !== "object" || Array.isArray(params.answers)) {
87
+ throw new Error("runtime.user_input.respond requires params.answers");
88
+ }
89
+ return { requestId: params.requestId, answers: params.answers };
90
+ }
78
91
  function requireLoginStartParams(event) {
79
92
  const params = getObjectParams(event);
80
93
  if (!params || typeof params.provider !== "string" || params.provider.length === 0) {
81
94
  throw new Error("login.start requires params.provider");
82
95
  }
83
- return { provider: params.provider };
96
+ if (params.method !== undefined && params.method !== "device_code" && params.method !== "browser_oauth") {
97
+ throw new Error("login.start params.method must be device_code or browser_oauth");
98
+ }
99
+ return { provider: params.provider, method: params.method };
84
100
  }
85
101
  function requireLoginCompleteParams(event) {
86
102
  const params = getObjectParams(event);
@@ -90,10 +106,28 @@ function requireLoginCompleteParams(event) {
90
106
  if (params.code !== undefined && typeof params.code !== "string") {
91
107
  throw new Error("login.complete params.code must be a string when provided");
92
108
  }
93
- if (typeof params.state !== "string" || params.state.length === 0) {
94
- throw new Error("login.complete requires params.state");
109
+ const flowId = typeof params.flowId === "string" && params.flowId.length > 0
110
+ ? params.flowId
111
+ : typeof params.state === "string" && params.state.length > 0
112
+ ? params.state
113
+ : undefined;
114
+ if (!flowId)
115
+ throw new Error("login.complete requires params.flowId");
116
+ return { provider: params.provider, code: params.code, flowId };
117
+ }
118
+ function requireLoginCancelParams(event) {
119
+ const params = getObjectParams(event);
120
+ if (!params || typeof params.provider !== "string" || params.provider.length === 0) {
121
+ throw new Error("login.cancel requires params.provider");
95
122
  }
96
- return { provider: params.provider, code: params.code, state: params.state };
123
+ const flowId = typeof params.flowId === "string" && params.flowId.length > 0
124
+ ? params.flowId
125
+ : typeof params.state === "string" && params.state.length > 0
126
+ ? params.state
127
+ : undefined;
128
+ if (!flowId)
129
+ throw new Error("login.cancel requires params.flowId");
130
+ return { provider: params.provider, flowId };
97
131
  }
98
132
  function requireLoginApiKeyParams(event) {
99
133
  const params = getObjectParams(event);
@@ -121,11 +155,18 @@ export const piboCorePlugin = definePiboPlugin({
121
155
  id: "pibo.core",
122
156
  name: "Pibo Core",
123
157
  register(api) {
158
+ api.registerAgentRuntimeDriver(PI_AGENT_RUNTIME_DRIVER);
159
+ api.registerAgentRuntimeInstance({ id: "pi", adapterId: "pi", displayName: "Pi Coding Agent" });
124
160
  api.registerSkill({
125
161
  name: "pi-agent-harness",
126
162
  path: builtinSkillPath("pi-agent-harness"),
127
163
  kind: "builtin",
128
164
  });
165
+ api.registerSkill({
166
+ name: "pibo-agent-runtime-adapter",
167
+ path: builtinSkillPath("pibo-agent-runtime-adapter"),
168
+ kind: "builtin",
169
+ });
129
170
  api.registerSkill({
130
171
  name: "pibo-spec-writing",
131
172
  path: builtinSkillPath("pibo-spec-writing"),
@@ -203,6 +244,26 @@ export const piboCorePlugin = definePiboPlugin({
203
244
  return await context.compact(customInstructions);
204
245
  },
205
246
  });
247
+ api.registerGatewayAction({
248
+ name: "runtime.approval.respond",
249
+ description: "Respond to a pending runtime approval request.",
250
+ hidden: true,
251
+ async execute(context, event) {
252
+ const params = requireApprovalResponseParams(event);
253
+ await context.respondToApproval(params.requestId, params.decision);
254
+ return { requestId: params.requestId, responded: true };
255
+ },
256
+ });
257
+ api.registerGatewayAction({
258
+ name: "runtime.user_input.respond",
259
+ description: "Respond to a pending structured runtime user-input request.",
260
+ hidden: true,
261
+ async execute(context, event) {
262
+ const params = requireUserInputResponseParams(event);
263
+ await context.respondToUserInput(params.requestId, params.answers);
264
+ return { requestId: params.requestId, responded: true };
265
+ },
266
+ });
206
267
  api.registerGatewayAction({
207
268
  name: "session_id",
208
269
  description: "Return the routed Pibo session id.",
@@ -255,7 +316,7 @@ export const piboCorePlugin = definePiboPlugin({
255
316
  });
256
317
  api.registerGatewayAction({
257
318
  name: "thinking",
258
- description: "Show or set the routed Pi thinking level.",
319
+ description: "Show or set the active runtime reasoning level.",
259
320
  slashCommands: ["thinking"],
260
321
  execute(context, event) {
261
322
  const params = getThinkingParams(event);
@@ -346,81 +407,164 @@ export const piboCorePlugin = definePiboPlugin({
346
407
  });
347
408
  api.registerGatewayAction({
348
409
  name: "login",
349
- description: "Open the interactive provider login menu.",
410
+ description: "Open the interactive provider login menu for the active runtime.",
350
411
  slashCommands: ["login"],
351
- execute() {
352
- const statuses = new Map(getLoginStatus().map((status) => [status.id, status.configured]));
412
+ async execute(context) {
413
+ const statuses = await context.getRuntimeAuthStatus();
353
414
  return {
354
415
  action: "show_login_menu",
355
- providers: LOGIN_PROVIDERS.map((provider) => ({
356
- ...provider,
357
- authMethods: [...provider.authMethods],
358
- configured: statuses.get(provider.id) ?? false,
416
+ runtimeInstanceId: context.runtimeInstanceId,
417
+ providers: statuses.map((status) => ({
418
+ id: status.id,
419
+ name: status.displayName ?? status.id,
420
+ authMethods: status.methods.map((method) => method.id),
421
+ configured: status.configured,
422
+ state: status.state,
423
+ message: status.message,
359
424
  })),
360
425
  };
361
426
  },
362
427
  });
363
428
  api.registerGatewayAction({
364
429
  name: "model",
365
- description: "Open the interactive model selector for authenticated providers.",
430
+ description: "Open the interactive model selector for the active runtime.",
366
431
  slashCommands: ["model"],
367
- async execute() {
432
+ async execute(context) {
433
+ const runtimeCatalog = await context.getModelCatalog();
434
+ if (runtimeCatalog) {
435
+ let authStatusAvailable = false;
436
+ let authStatuses = new Map();
437
+ try {
438
+ const statuses = await context.getRuntimeAuthStatus();
439
+ authStatusAvailable = true;
440
+ authStatuses = new Map(statuses.map((status) => [status.id, status.configured]));
441
+ }
442
+ catch {
443
+ // Runtimes that do not declare auth may use model-catalog compatibility metadata.
444
+ }
445
+ const providers = new Map();
446
+ for (const model of runtimeCatalog.models) {
447
+ const providerId = model.provider ?? runtimeCatalog.runtimeInstanceId;
448
+ const providerLabel = typeof model.options?.providerDisplayName === "string"
449
+ ? model.options.providerDisplayName
450
+ : providerId;
451
+ const authConfigured = authStatuses.get(providerId)
452
+ ?? (authStatusAvailable
453
+ ? false
454
+ : typeof model.options?.authConfigured === "boolean"
455
+ ? model.options.authConfigured
456
+ : !context.runtimeAuthRequired);
457
+ let provider = providers.get(providerId);
458
+ if (!provider) {
459
+ provider = { id: providerId, label: providerLabel, authConfigured, models: [] };
460
+ providers.set(providerId, provider);
461
+ }
462
+ provider.models.push({
463
+ provider: providerId,
464
+ id: model.id,
465
+ label: model.displayName ?? model.id,
466
+ ...(model.reasoningOptions ? { supportsReasoning: model.reasoningOptions.length > 0 } : {}),
467
+ });
468
+ }
469
+ return { action: "show_model_menu", providers: [...providers.values()] };
470
+ }
368
471
  const catalog = await loadModelCatalog(process.cwd());
369
472
  return {
370
473
  action: "show_model_menu",
371
- providers: catalog.providers
372
- .filter((provider) => provider.authConfigured)
373
- .map((provider) => ({
474
+ providers: catalog.providers.map((provider) => ({
374
475
  ...provider,
375
- models: provider.models.filter((model) => model.authConfigured !== false),
476
+ models: provider.models,
376
477
  })),
377
478
  };
378
479
  },
379
480
  });
380
481
  api.registerGatewayAction({
381
482
  name: "login.start",
382
- description: "Start an OAuth login flow for a provider. Returns a URL to open in a browser.",
483
+ description: "Start a provider login flow for the active runtime.",
383
484
  slashCommands: [],
384
- async execute(_context, event) {
485
+ async execute(context, event) {
385
486
  const params = requireLoginStartParams(event);
386
- return await startLogin(params.provider);
487
+ const status = (await context.getRuntimeAuthStatus()).find((candidate) => candidate.id === params.provider);
488
+ const method = params.method ?? status?.methods.find((candidate) => candidate.id !== "api_key")?.id;
489
+ if (method !== "device_code" && method !== "browser_oauth") {
490
+ throw new Error(`Provider "${params.provider}" does not expose an interactive login method.`);
491
+ }
492
+ const result = await context.startRuntimeAuth({ providerId: params.provider, method });
493
+ return {
494
+ ...result,
495
+ runtimeInstanceId: context.runtimeInstanceId,
496
+ ...(result.flow ? {
497
+ type: result.flow.method,
498
+ url: result.flow.verificationUrl,
499
+ verificationUrl: result.flow.verificationUrl,
500
+ userCode: result.flow.userCode,
501
+ instructions: result.flow.instructions,
502
+ flowId: result.flow.flowId,
503
+ state: result.flow.flowId,
504
+ } : {}),
505
+ };
387
506
  },
388
507
  });
389
508
  api.registerGatewayAction({
390
509
  name: "login.complete",
391
- description: "Complete an OAuth login flow with the authorization code from the provider callback.",
510
+ description: "Read or complete a provider login flow for the active runtime.",
392
511
  slashCommands: [],
393
- async execute(_context, event) {
512
+ async execute(context, event) {
394
513
  const params = requireLoginCompleteParams(event);
395
- return await completeLogin(params.provider, params.code, params.state);
514
+ return {
515
+ ...(await context.completeRuntimeAuth({ providerId: params.provider, flowId: params.flowId, code: params.code })),
516
+ runtimeInstanceId: context.runtimeInstanceId,
517
+ };
396
518
  },
397
519
  });
398
520
  api.registerGatewayAction({
399
521
  name: "login.apikey",
400
- description: "Set an API key directly for a provider.",
522
+ description: "Set an API key for a provider on the active runtime.",
401
523
  slashCommands: [],
402
- execute(_context, event) {
524
+ async execute(context, event) {
403
525
  const params = requireLoginApiKeyParams(event);
404
- return setApiKey(params.provider, params.apiKey);
526
+ return {
527
+ ...(await context.startRuntimeAuth({ providerId: params.provider, method: "api_key", apiKey: params.apiKey })),
528
+ runtimeInstanceId: context.runtimeInstanceId,
529
+ };
530
+ },
531
+ });
532
+ api.registerGatewayAction({
533
+ name: "login.cancel",
534
+ description: "Cancel a pending provider login for the active runtime.",
535
+ slashCommands: [],
536
+ async execute(context, event) {
537
+ const params = requireLoginCancelParams(event);
538
+ return {
539
+ ...(await context.cancelRuntimeAuth({ providerId: params.provider, flowId: params.flowId })),
540
+ runtimeInstanceId: context.runtimeInstanceId,
541
+ };
405
542
  },
406
543
  });
407
544
  api.registerGatewayAction({
408
545
  name: "login.status",
409
- description: "Check the authentication status for providers.",
546
+ description: "Check provider authentication status for the active runtime.",
410
547
  slashCommands: [],
411
- execute(_context, event) {
548
+ async execute(context, event) {
412
549
  const params = getObjectParams(event);
413
550
  const provider = typeof params?.provider === "string" ? params.provider : undefined;
414
- return { providers: getLoginStatus(provider) };
551
+ const providers = await context.getRuntimeAuthStatus();
552
+ return {
553
+ runtimeInstanceId: context.runtimeInstanceId,
554
+ providers: provider ? providers.filter((status) => status.id === provider) : providers,
555
+ };
415
556
  },
416
557
  });
417
558
  api.registerGatewayAction({
418
559
  name: "logout",
419
- description: "Remove stored credentials for a provider.",
560
+ description: "Remove stored credentials for a provider on the active runtime.",
420
561
  slashCommands: [],
421
- execute(_context, event) {
562
+ async execute(context, event) {
422
563
  const params = requireLogoutParams(event);
423
- return removeLogin(params.provider);
564
+ return {
565
+ ...(await context.logoutRuntimeAuth({ providerId: params.provider })),
566
+ runtimeInstanceId: context.runtimeInstanceId,
567
+ };
424
568
  },
425
569
  });
426
570
  },
@@ -443,11 +587,11 @@ export const piboGatewayProducerPlugin = definePiboPlugin({
443
587
  },
444
588
  });
445
589
  export function createDefaultPiboPlugins() {
446
- return [piboCorePlugin, piboCodexCompatPlugin, piboWebAnnotationsPlugin];
590
+ return [piboCorePlugin, piboCodexNativePlugin, piboCodexCompatPlugin, piboWebAnnotationsPlugin];
447
591
  }
448
592
  export function createGatewayProducerPiboPluginRegistry() {
449
593
  return PiboPluginRegistry.create({
450
- plugins: [piboCorePlugin, piboGatewayProducerPlugin, piboCodexCompatPlugin, piboWebAnnotationsPlugin],
594
+ plugins: [piboCorePlugin, piboCodexNativePlugin, piboGatewayProducerPlugin, piboCodexCompatPlugin, piboWebAnnotationsPlugin],
451
595
  });
452
596
  }
453
597
  export function createDefaultPiboPluginRegistry() {
@@ -457,12 +601,6 @@ export function selectDefaultPiboProfileName(registry) {
457
601
  const names = registry.getProfileNames();
458
602
  return names.includes(DEFAULT_PIBO_PROFILE_NAME) ? DEFAULT_PIBO_PROFILE_NAME : names[0] ?? DEFAULT_PIBO_PROFILE_NAME;
459
603
  }
460
- export function createDefaultPiboProfile() {
461
- return new InitialSessionContextBuilder(DEFAULT_PIBO_PROFILE_NAME)
462
- .withBuiltinToolNames(["read", "bash", "edit", "write"])
463
- .withToolPackages({ goalControl: true })
464
- .createSession();
465
- }
466
604
  export function resolvePiboProfileNameFromRegistryOrDefault(registry, profileName) {
467
605
  const requestedProfileName = profileName ?? selectDefaultPiboProfileName(registry);
468
606
  try {
@@ -0,0 +1,29 @@
1
+ import { CODEX_NATIVE_ADAPTER_ID, CODEX_NATIVE_AGENT_RUNTIME_DRIVER, } from "../agent-runtimes/codex-native/adapter.js";
2
+ import { InitialSessionContextBuilder } from "../core/profiles.js";
3
+ import { definePiboPlugin } from "./registry.js";
4
+ export const CODEX_NATIVE_RUNTIME_INSTANCE_ID = "codex-native";
5
+ export const CODEX_NATIVE_PROFILE_NAME = "codex-native";
6
+ export const piboCodexNativePlugin = definePiboPlugin({
7
+ id: "pibo.codex-native",
8
+ name: "Pibo Native Codex",
9
+ register(api) {
10
+ api.registerAgentRuntimeDriver(CODEX_NATIVE_AGENT_RUNTIME_DRIVER);
11
+ api.registerAgentRuntimeInstance({
12
+ id: CODEX_NATIVE_RUNTIME_INSTANCE_ID,
13
+ adapterId: CODEX_NATIVE_ADAPTER_ID,
14
+ displayName: "Native Codex App Server",
15
+ });
16
+ api.registerProfile({
17
+ name: CODEX_NATIVE_PROFILE_NAME,
18
+ description: "Native Codex App Server profile. Distinct from the Pi-backed Codex compatibility profile.",
19
+ create() {
20
+ return new InitialSessionContextBuilder(CODEX_NATIVE_PROFILE_NAME)
21
+ .withAgentRuntime(CODEX_NATIVE_RUNTIME_INSTANCE_ID)
22
+ .withBuiltinTools("disabled")
23
+ .withBuiltinToolNames([])
24
+ .withToolPackages({ goalControl: true })
25
+ .createSession();
26
+ },
27
+ });
28
+ },
29
+ });