@pasko70/pibo 3.6.2 → 3.6.4
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.
- package/dist/agent-runtime/auth-contract.js +215 -0
- package/dist/agent-runtime/registry.js +1 -214
- package/dist/agent-runtime/routed-session.js +7 -0
- package/dist/agent-runtimes/codex-native/turn.js +2 -2
- package/dist/agent-runtimes/pi/auth.js +1 -0
- package/dist/agent-runtimes/pi/model-catalog.js +2 -0
- package/dist/agent-runtimes/pi/runtime.js +2 -0
- package/dist/apps/chat/trace-v2.js +1 -0
- package/dist/apps/chat/web-app.js +1 -0
- package/dist/apps/chat-ui/assets/{dist-fEoIZhiB.js → dist-BHiMQOG6.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CkvR8VSK.js → dist-BfNGI8zD.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-Bw_Uk-TC.js → dist-Cf5vD7GX.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-CRCfZH6c.js → dist-Ds-8WrKd.js} +1 -1
- package/dist/apps/chat-ui/assets/{dist-Di_Ioy0T.js → dist-iE0b01WP.js} +1 -1
- package/dist/apps/chat-ui/assets/{index-BDe_bSi9.js → index-BWhdVZpM.js} +86 -86
- package/dist/apps/chat-ui/assets/index-VZBlQTo5.css +1 -0
- package/dist/apps/chat-ui/index.html +2 -2
- package/dist/apps/chat-vscode-web/assets/{index-l2TxPbpk.js → index-CtaeZkpG.js} +4 -4
- package/dist/apps/chat-vscode-web/index.html +1 -1
- package/dist/core/session-router.js +112 -3
- package/dist/data/chat-read-projections.js +46 -33
- package/dist/mcp/config.js +13 -48
- package/dist/providers/meta-muse.js +51 -0
- package/dist/runs/resource-isolation.js +3 -125
- package/dist/runs/windows-process-tree.js +132 -0
- package/dist/session-ui/terminalRows.js +29 -3
- package/dist/shared/trace-engine.js +2 -1
- package/dist/shared/trace-event-projection.js +80 -0
- package/dist/shared/trace-patch-nodes.js +14 -0
- package/dist/subagents/context.js +9 -3
- package/dist/subagents/observations.js +1 -1
- package/dist/subagents/tool.js +14 -6
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/packages/workflows/dist/runtime/adapter-node.d.ts.map +1 -1
- package/packages/workflows/dist/runtime/adapter-node.js +1 -13
- package/packages/workflows/dist/runtime/adapter-node.js.map +1 -1
- package/packages/workflows/dist/runtime/dispatch-failures.d.ts +1 -0
- package/packages/workflows/dist/runtime/dispatch-failures.d.ts.map +1 -1
- package/packages/workflows/dist/runtime/dispatch-failures.js +12 -0
- package/packages/workflows/dist/runtime/dispatch-failures.js.map +1 -1
- package/packages/workflows/dist/runtime/edge-transfer.d.ts.map +1 -1
- package/packages/workflows/dist/runtime/edge-transfer.js +1 -12
- package/packages/workflows/dist/runtime/edge-transfer.js.map +1 -1
- package/dist/apps/chat-ui/assets/index-zmsI0NvB.css +0 -1
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { AGENT_RUNTIME_AUTH_COMPLETION_MODES, AGENT_RUNTIME_AUTH_METHOD_IDS, redactAgentRuntimeAuthText, } from "./auth.js";
|
|
2
|
+
import { AgentRuntimeAuthError, AgentRuntimeContractError, AgentRuntimeRegistrationError, } from "./errors.js";
|
|
3
|
+
const AUTH_ID_PATTERN = /^[a-z0-9][a-z0-9._-]{0,127}$/;
|
|
4
|
+
const AUTH_STATES = new Set([
|
|
5
|
+
"connected",
|
|
6
|
+
"disconnected",
|
|
7
|
+
"pending",
|
|
8
|
+
"partial",
|
|
9
|
+
"unsupported",
|
|
10
|
+
"failed",
|
|
11
|
+
]);
|
|
12
|
+
export function assertAuthId(value, label, runtimeInstanceId = "auth") {
|
|
13
|
+
if (!AUTH_ID_PATTERN.test(value)) {
|
|
14
|
+
throw new AgentRuntimeContractError(runtimeInstanceId, `${label} must match ${AUTH_ID_PATTERN}.`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function scopedAuthContractError(error, runtimeInstanceId) {
|
|
18
|
+
return error.runtimeInstanceId === runtimeInstanceId
|
|
19
|
+
? error
|
|
20
|
+
: new AgentRuntimeContractError(runtimeInstanceId, error.message, { cause: error });
|
|
21
|
+
}
|
|
22
|
+
function boundedAuthText(value, label, maxLength) {
|
|
23
|
+
if (value === undefined)
|
|
24
|
+
return undefined;
|
|
25
|
+
if (typeof value !== "string" || value.length === 0 || value.length > maxLength) {
|
|
26
|
+
throw new AgentRuntimeContractError("auth", `${label} must be a non-empty string no longer than ${maxLength} characters.`);
|
|
27
|
+
}
|
|
28
|
+
return redactAgentRuntimeAuthText(value, maxLength);
|
|
29
|
+
}
|
|
30
|
+
export function safeAdapterAuthError(error, operation) {
|
|
31
|
+
if (error instanceof AgentRuntimeAuthError) {
|
|
32
|
+
const code = /^[a-z][a-z0-9._-]{0,63}$/.test(error.code) ? error.code : "runtime_auth_failed";
|
|
33
|
+
return new AgentRuntimeAuthError(code, redactAgentRuntimeAuthText(error.message), error.retryable === true);
|
|
34
|
+
}
|
|
35
|
+
return new AgentRuntimeAuthError("runtime_auth_failed", `Runtime provider authentication ${operation} failed safely.`, true);
|
|
36
|
+
}
|
|
37
|
+
function cloneAuthDetails(value) {
|
|
38
|
+
if (value === undefined)
|
|
39
|
+
return undefined;
|
|
40
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
41
|
+
throw new AgentRuntimeContractError("auth", "Auth details must be an object when provided.");
|
|
42
|
+
}
|
|
43
|
+
const details = {};
|
|
44
|
+
if (value.accountType !== undefined) {
|
|
45
|
+
if (!["api_key", "oauth", "chatgpt", "unknown"].includes(value.accountType)) {
|
|
46
|
+
throw new AgentRuntimeContractError("auth", "Auth details contain an invalid account type.");
|
|
47
|
+
}
|
|
48
|
+
details.accountType = value.accountType;
|
|
49
|
+
}
|
|
50
|
+
if (value.planType !== undefined) {
|
|
51
|
+
if (!/^[a-z0-9][a-z0-9._-]{0,63}$/i.test(value.planType)) {
|
|
52
|
+
throw new AgentRuntimeContractError("auth", "Auth details contain an invalid plan type.");
|
|
53
|
+
}
|
|
54
|
+
details.planType = value.planType;
|
|
55
|
+
}
|
|
56
|
+
return Object.keys(details).length > 0 ? details : undefined;
|
|
57
|
+
}
|
|
58
|
+
function declaredAuthMethod(methods, methodId) {
|
|
59
|
+
const method = methods.find((candidate) => candidate.id === methodId);
|
|
60
|
+
if (!method)
|
|
61
|
+
throw new AgentRuntimeContractError("auth", `Auth method "${methodId}" was not declared by the runtime adapter.`);
|
|
62
|
+
return method;
|
|
63
|
+
}
|
|
64
|
+
function cloneAuthFlow(value, methods) {
|
|
65
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
66
|
+
throw new AgentRuntimeContractError("auth", "Auth flow must be an object.");
|
|
67
|
+
}
|
|
68
|
+
assertAuthId(value.flowId, "Auth flow id");
|
|
69
|
+
if (!AGENT_RUNTIME_AUTH_METHOD_IDS.includes(value.method)) {
|
|
70
|
+
throw new AgentRuntimeContractError("auth", `Auth flow method "${String(value.method)}" is invalid.`);
|
|
71
|
+
}
|
|
72
|
+
if (!AGENT_RUNTIME_AUTH_COMPLETION_MODES.includes(value.completion)) {
|
|
73
|
+
throw new AgentRuntimeContractError("auth", `Auth flow completion mode "${String(value.completion)}" is invalid.`);
|
|
74
|
+
}
|
|
75
|
+
const declared = declaredAuthMethod(methods, value.method);
|
|
76
|
+
if (declared.completion !== value.completion) {
|
|
77
|
+
throw new AgentRuntimeContractError("auth", `Auth flow completion mode does not match declared method "${value.method}".`);
|
|
78
|
+
}
|
|
79
|
+
if (typeof value.startedAt !== "string" || !Number.isFinite(Date.parse(value.startedAt))) {
|
|
80
|
+
throw new AgentRuntimeContractError("auth", "Auth flow startedAt must be an ISO timestamp.");
|
|
81
|
+
}
|
|
82
|
+
if (value.expiresAt !== undefined
|
|
83
|
+
&& (typeof value.expiresAt !== "string" || !Number.isFinite(Date.parse(value.expiresAt)))) {
|
|
84
|
+
throw new AgentRuntimeContractError("auth", "Auth flow expiresAt must be an ISO timestamp.");
|
|
85
|
+
}
|
|
86
|
+
const verificationUrl = boundedAuthText(value.verificationUrl, "Auth verification URL", 2_048);
|
|
87
|
+
if (verificationUrl) {
|
|
88
|
+
let parsed;
|
|
89
|
+
try {
|
|
90
|
+
parsed = new URL(verificationUrl);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
throw new AgentRuntimeContractError("auth", "Auth verification URL is invalid.");
|
|
94
|
+
}
|
|
95
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
96
|
+
throw new AgentRuntimeContractError("auth", "Auth verification URL must use HTTP or HTTPS.");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
flowId: value.flowId,
|
|
101
|
+
method: value.method,
|
|
102
|
+
completion: value.completion,
|
|
103
|
+
startedAt: new Date(value.startedAt).toISOString(),
|
|
104
|
+
...(value.expiresAt ? { expiresAt: new Date(value.expiresAt).toISOString() } : {}),
|
|
105
|
+
...(verificationUrl ? { verificationUrl } : {}),
|
|
106
|
+
...(value.userCode ? { userCode: boundedAuthText(value.userCode, "Auth user code", 128) } : {}),
|
|
107
|
+
...(value.instructions ? { instructions: boundedAuthText(value.instructions, "Auth instructions", 1_000) } : {}),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function validateAuthConfiguredState(state, configured) {
|
|
111
|
+
if (state === "connected" && !configured) {
|
|
112
|
+
throw new AgentRuntimeContractError("auth", "Connected auth status must be configured.");
|
|
113
|
+
}
|
|
114
|
+
if ((state === "disconnected" || state === "unsupported") && configured) {
|
|
115
|
+
throw new AgentRuntimeContractError("auth", `${state} auth status cannot be configured.`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
export function cloneAuthStatus(value, declaredMethods) {
|
|
119
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
120
|
+
throw new AgentRuntimeContractError("auth", "Auth provider status must be an object.");
|
|
121
|
+
}
|
|
122
|
+
assertAuthId(value.id, "Auth provider id");
|
|
123
|
+
if (!AUTH_STATES.has(value.state)) {
|
|
124
|
+
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" reported invalid state "${String(value.state)}".`);
|
|
125
|
+
}
|
|
126
|
+
if (typeof value.configured !== "boolean") {
|
|
127
|
+
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" must report configured as a boolean.`);
|
|
128
|
+
}
|
|
129
|
+
validateAuthConfiguredState(value.state, value.configured);
|
|
130
|
+
if (!Array.isArray(value.methods)) {
|
|
131
|
+
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" must report methods.`);
|
|
132
|
+
}
|
|
133
|
+
const seen = new Set();
|
|
134
|
+
const methods = value.methods.map((method) => {
|
|
135
|
+
if (!method || typeof method !== "object" || Array.isArray(method)) {
|
|
136
|
+
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" reported an invalid method.`);
|
|
137
|
+
}
|
|
138
|
+
if (seen.has(method.id))
|
|
139
|
+
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" repeats method "${method.id}".`);
|
|
140
|
+
seen.add(method.id);
|
|
141
|
+
const declared = declaredAuthMethod(declaredMethods, method.id);
|
|
142
|
+
if (declared.completion !== method.completion) {
|
|
143
|
+
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" method "${method.id}" has a mismatched completion mode.`);
|
|
144
|
+
}
|
|
145
|
+
return { ...declared };
|
|
146
|
+
});
|
|
147
|
+
if (value.state === "pending" && !value.pending) {
|
|
148
|
+
throw new AgentRuntimeContractError("auth", `Pending auth provider "${value.id}" must include a flow.`);
|
|
149
|
+
}
|
|
150
|
+
if (value.state !== "pending" && value.pending) {
|
|
151
|
+
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" includes a flow while state is "${value.state}".`);
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
id: value.id,
|
|
155
|
+
...(value.displayName ? { displayName: boundedAuthText(value.displayName, "Auth provider display name", 160) } : {}),
|
|
156
|
+
state: value.state,
|
|
157
|
+
configured: value.configured,
|
|
158
|
+
methods,
|
|
159
|
+
...(value.pending ? { pending: cloneAuthFlow(value.pending, declaredMethods) } : {}),
|
|
160
|
+
...(value.message ? { message: boundedAuthText(value.message, "Auth status message", 1_000) } : {}),
|
|
161
|
+
...(value.details ? { details: cloneAuthDetails(value.details) } : {}),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
export function cloneAuthOperationResult(value, inputProviderId, declaredMethods) {
|
|
165
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
166
|
+
throw new AgentRuntimeContractError("auth", "Auth operation result must be an object.");
|
|
167
|
+
}
|
|
168
|
+
assertAuthId(value.providerId, "Auth result provider id");
|
|
169
|
+
if (value.providerId !== inputProviderId) {
|
|
170
|
+
throw new AgentRuntimeContractError("auth", `Auth result provider "${value.providerId}" does not match requested provider "${inputProviderId}".`);
|
|
171
|
+
}
|
|
172
|
+
if (!AUTH_STATES.has(value.state)) {
|
|
173
|
+
throw new AgentRuntimeContractError("auth", `Auth result reported invalid state "${String(value.state)}".`);
|
|
174
|
+
}
|
|
175
|
+
if (typeof value.configured !== "boolean") {
|
|
176
|
+
throw new AgentRuntimeContractError("auth", "Auth result configured must be a boolean.");
|
|
177
|
+
}
|
|
178
|
+
validateAuthConfiguredState(value.state, value.configured);
|
|
179
|
+
if (value.state === "pending" && !value.flow) {
|
|
180
|
+
throw new AgentRuntimeContractError("auth", "Pending auth result must include a flow.");
|
|
181
|
+
}
|
|
182
|
+
if (value.state !== "pending" && value.flow) {
|
|
183
|
+
throw new AgentRuntimeContractError("auth", `Auth result includes a flow while state is "${value.state}".`);
|
|
184
|
+
}
|
|
185
|
+
return {
|
|
186
|
+
providerId: value.providerId,
|
|
187
|
+
state: value.state,
|
|
188
|
+
configured: value.configured,
|
|
189
|
+
...(value.flow ? { flow: cloneAuthFlow(value.flow, declaredMethods) } : {}),
|
|
190
|
+
...(value.message ? { message: boundedAuthText(value.message, "Auth result message", 1_000) } : {}),
|
|
191
|
+
...(value.details ? { details: cloneAuthDetails(value.details) } : {}),
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
export function assertAdapterAuthContract(adapter) {
|
|
195
|
+
const auth = adapter.descriptor.capabilities.auth;
|
|
196
|
+
if (auth.status !== Boolean(adapter.getAuthStatus)) {
|
|
197
|
+
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" auth.status must match getAuthStatus().`);
|
|
198
|
+
}
|
|
199
|
+
if ((auth.methods.length > 0) !== Boolean(adapter.startAuth)) {
|
|
200
|
+
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" declared auth methods must match startAuth().`);
|
|
201
|
+
}
|
|
202
|
+
const needsCompletion = auth.methods.some((method) => method.completion !== "immediate");
|
|
203
|
+
if (needsCompletion !== Boolean(adapter.completeAuth)) {
|
|
204
|
+
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" non-immediate auth methods must match completeAuth().`);
|
|
205
|
+
}
|
|
206
|
+
if (needsCompletion && !adapter.disposeAuth) {
|
|
207
|
+
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" non-immediate auth methods require disposeAuth().`);
|
|
208
|
+
}
|
|
209
|
+
if (auth.cancel !== Boolean(adapter.cancelAuth)) {
|
|
210
|
+
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" auth.cancel must match cancelAuth().`);
|
|
211
|
+
}
|
|
212
|
+
if (auth.logout !== Boolean(adapter.logoutAuth)) {
|
|
213
|
+
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" auth.logout must match logoutAuth().`);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
@@ -2,20 +2,11 @@ import { validateAgentRuntimeCapabilities } from "./capabilities.js";
|
|
|
2
2
|
import { assertAgentRuntimeSessionContract } from "./contract.js";
|
|
3
3
|
import { validateAgentRuntimeProfileCapabilities } from "./profile-validation.js";
|
|
4
4
|
import { AgentRuntimeAuthError, AgentRuntimeCapabilityUnavailableError, AgentRuntimeContractError, AgentRuntimeRegistrationError, AgentRuntimeUnavailableError, } from "./errors.js";
|
|
5
|
-
import {
|
|
5
|
+
import { assertAdapterAuthContract, assertAuthId, cloneAuthOperationResult, cloneAuthStatus, safeAdapterAuthError, scopedAuthContractError, } from "./auth-contract.js";
|
|
6
6
|
const RUNTIME_ID_PATTERN = /^[a-z][a-z0-9]*(?:[._-][a-z0-9]+)*$/;
|
|
7
|
-
const AUTH_ID_PATTERN = /^[a-z0-9][a-z0-9._-]{0,127}$/;
|
|
8
7
|
const MAX_AUTH_API_KEY_LENGTH = 64 * 1_024;
|
|
9
8
|
const MAX_AUTH_COMPLETION_CODE_LENGTH = 16 * 1_024;
|
|
10
9
|
const MAX_AUTH_PROVIDERS = 256;
|
|
11
|
-
const AUTH_STATES = new Set([
|
|
12
|
-
"connected",
|
|
13
|
-
"disconnected",
|
|
14
|
-
"pending",
|
|
15
|
-
"partial",
|
|
16
|
-
"unsupported",
|
|
17
|
-
"failed",
|
|
18
|
-
]);
|
|
19
10
|
function assertRuntimeId(value, label) {
|
|
20
11
|
if (!RUNTIME_ID_PATTERN.test(value)) {
|
|
21
12
|
throw new AgentRuntimeRegistrationError(`${label} "${value}" must match ${RUNTIME_ID_PATTERN}.`);
|
|
@@ -24,210 +15,6 @@ function assertRuntimeId(value, label) {
|
|
|
24
15
|
function cloneConfig(config) {
|
|
25
16
|
return structuredClone(config);
|
|
26
17
|
}
|
|
27
|
-
function assertAuthId(value, label, runtimeInstanceId = "auth") {
|
|
28
|
-
if (!AUTH_ID_PATTERN.test(value)) {
|
|
29
|
-
throw new AgentRuntimeContractError(runtimeInstanceId, `${label} must match ${AUTH_ID_PATTERN}.`);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function scopedAuthContractError(error, runtimeInstanceId) {
|
|
33
|
-
return error.runtimeInstanceId === runtimeInstanceId
|
|
34
|
-
? error
|
|
35
|
-
: new AgentRuntimeContractError(runtimeInstanceId, error.message, { cause: error });
|
|
36
|
-
}
|
|
37
|
-
function boundedAuthText(value, label, maxLength) {
|
|
38
|
-
if (value === undefined)
|
|
39
|
-
return undefined;
|
|
40
|
-
if (typeof value !== "string" || value.length === 0 || value.length > maxLength) {
|
|
41
|
-
throw new AgentRuntimeContractError("auth", `${label} must be a non-empty string no longer than ${maxLength} characters.`);
|
|
42
|
-
}
|
|
43
|
-
return redactAgentRuntimeAuthText(value, maxLength);
|
|
44
|
-
}
|
|
45
|
-
function safeAdapterAuthError(error, operation) {
|
|
46
|
-
if (error instanceof AgentRuntimeAuthError) {
|
|
47
|
-
const code = /^[a-z][a-z0-9._-]{0,63}$/.test(error.code) ? error.code : "runtime_auth_failed";
|
|
48
|
-
return new AgentRuntimeAuthError(code, redactAgentRuntimeAuthText(error.message), error.retryable === true);
|
|
49
|
-
}
|
|
50
|
-
return new AgentRuntimeAuthError("runtime_auth_failed", `Runtime provider authentication ${operation} failed safely.`, true);
|
|
51
|
-
}
|
|
52
|
-
function cloneAuthDetails(value) {
|
|
53
|
-
if (value === undefined)
|
|
54
|
-
return undefined;
|
|
55
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
56
|
-
throw new AgentRuntimeContractError("auth", "Auth details must be an object when provided.");
|
|
57
|
-
}
|
|
58
|
-
const details = {};
|
|
59
|
-
if (value.accountType !== undefined) {
|
|
60
|
-
if (!["api_key", "oauth", "chatgpt", "unknown"].includes(value.accountType)) {
|
|
61
|
-
throw new AgentRuntimeContractError("auth", "Auth details contain an invalid account type.");
|
|
62
|
-
}
|
|
63
|
-
details.accountType = value.accountType;
|
|
64
|
-
}
|
|
65
|
-
if (value.planType !== undefined) {
|
|
66
|
-
if (!/^[a-z0-9][a-z0-9._-]{0,63}$/i.test(value.planType)) {
|
|
67
|
-
throw new AgentRuntimeContractError("auth", "Auth details contain an invalid plan type.");
|
|
68
|
-
}
|
|
69
|
-
details.planType = value.planType;
|
|
70
|
-
}
|
|
71
|
-
return Object.keys(details).length > 0 ? details : undefined;
|
|
72
|
-
}
|
|
73
|
-
function declaredAuthMethod(methods, methodId) {
|
|
74
|
-
const method = methods.find((candidate) => candidate.id === methodId);
|
|
75
|
-
if (!method)
|
|
76
|
-
throw new AgentRuntimeContractError("auth", `Auth method "${methodId}" was not declared by the runtime adapter.`);
|
|
77
|
-
return method;
|
|
78
|
-
}
|
|
79
|
-
function cloneAuthFlow(value, methods) {
|
|
80
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
81
|
-
throw new AgentRuntimeContractError("auth", "Auth flow must be an object.");
|
|
82
|
-
}
|
|
83
|
-
assertAuthId(value.flowId, "Auth flow id");
|
|
84
|
-
if (!AGENT_RUNTIME_AUTH_METHOD_IDS.includes(value.method)) {
|
|
85
|
-
throw new AgentRuntimeContractError("auth", `Auth flow method "${String(value.method)}" is invalid.`);
|
|
86
|
-
}
|
|
87
|
-
if (!AGENT_RUNTIME_AUTH_COMPLETION_MODES.includes(value.completion)) {
|
|
88
|
-
throw new AgentRuntimeContractError("auth", `Auth flow completion mode "${String(value.completion)}" is invalid.`);
|
|
89
|
-
}
|
|
90
|
-
const declared = declaredAuthMethod(methods, value.method);
|
|
91
|
-
if (declared.completion !== value.completion) {
|
|
92
|
-
throw new AgentRuntimeContractError("auth", `Auth flow completion mode does not match declared method "${value.method}".`);
|
|
93
|
-
}
|
|
94
|
-
if (typeof value.startedAt !== "string" || !Number.isFinite(Date.parse(value.startedAt))) {
|
|
95
|
-
throw new AgentRuntimeContractError("auth", "Auth flow startedAt must be an ISO timestamp.");
|
|
96
|
-
}
|
|
97
|
-
if (value.expiresAt !== undefined
|
|
98
|
-
&& (typeof value.expiresAt !== "string" || !Number.isFinite(Date.parse(value.expiresAt)))) {
|
|
99
|
-
throw new AgentRuntimeContractError("auth", "Auth flow expiresAt must be an ISO timestamp.");
|
|
100
|
-
}
|
|
101
|
-
const verificationUrl = boundedAuthText(value.verificationUrl, "Auth verification URL", 2_048);
|
|
102
|
-
if (verificationUrl) {
|
|
103
|
-
let parsed;
|
|
104
|
-
try {
|
|
105
|
-
parsed = new URL(verificationUrl);
|
|
106
|
-
}
|
|
107
|
-
catch {
|
|
108
|
-
throw new AgentRuntimeContractError("auth", "Auth verification URL is invalid.");
|
|
109
|
-
}
|
|
110
|
-
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
111
|
-
throw new AgentRuntimeContractError("auth", "Auth verification URL must use HTTP or HTTPS.");
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
115
|
-
flowId: value.flowId,
|
|
116
|
-
method: value.method,
|
|
117
|
-
completion: value.completion,
|
|
118
|
-
startedAt: new Date(value.startedAt).toISOString(),
|
|
119
|
-
...(value.expiresAt ? { expiresAt: new Date(value.expiresAt).toISOString() } : {}),
|
|
120
|
-
...(verificationUrl ? { verificationUrl } : {}),
|
|
121
|
-
...(value.userCode ? { userCode: boundedAuthText(value.userCode, "Auth user code", 128) } : {}),
|
|
122
|
-
...(value.instructions ? { instructions: boundedAuthText(value.instructions, "Auth instructions", 1_000) } : {}),
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
function validateAuthConfiguredState(state, configured) {
|
|
126
|
-
if (state === "connected" && !configured) {
|
|
127
|
-
throw new AgentRuntimeContractError("auth", "Connected auth status must be configured.");
|
|
128
|
-
}
|
|
129
|
-
if ((state === "disconnected" || state === "unsupported") && configured) {
|
|
130
|
-
throw new AgentRuntimeContractError("auth", `${state} auth status cannot be configured.`);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
function cloneAuthStatus(value, declaredMethods) {
|
|
134
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
135
|
-
throw new AgentRuntimeContractError("auth", "Auth provider status must be an object.");
|
|
136
|
-
}
|
|
137
|
-
assertAuthId(value.id, "Auth provider id");
|
|
138
|
-
if (!AUTH_STATES.has(value.state)) {
|
|
139
|
-
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" reported invalid state "${String(value.state)}".`);
|
|
140
|
-
}
|
|
141
|
-
if (typeof value.configured !== "boolean") {
|
|
142
|
-
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" must report configured as a boolean.`);
|
|
143
|
-
}
|
|
144
|
-
validateAuthConfiguredState(value.state, value.configured);
|
|
145
|
-
if (!Array.isArray(value.methods)) {
|
|
146
|
-
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" must report methods.`);
|
|
147
|
-
}
|
|
148
|
-
const seen = new Set();
|
|
149
|
-
const methods = value.methods.map((method) => {
|
|
150
|
-
if (!method || typeof method !== "object" || Array.isArray(method)) {
|
|
151
|
-
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" reported an invalid method.`);
|
|
152
|
-
}
|
|
153
|
-
if (seen.has(method.id))
|
|
154
|
-
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" repeats method "${method.id}".`);
|
|
155
|
-
seen.add(method.id);
|
|
156
|
-
const declared = declaredAuthMethod(declaredMethods, method.id);
|
|
157
|
-
if (declared.completion !== method.completion) {
|
|
158
|
-
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" method "${method.id}" has a mismatched completion mode.`);
|
|
159
|
-
}
|
|
160
|
-
return { ...declared };
|
|
161
|
-
});
|
|
162
|
-
if (value.state === "pending" && !value.pending) {
|
|
163
|
-
throw new AgentRuntimeContractError("auth", `Pending auth provider "${value.id}" must include a flow.`);
|
|
164
|
-
}
|
|
165
|
-
if (value.state !== "pending" && value.pending) {
|
|
166
|
-
throw new AgentRuntimeContractError("auth", `Auth provider "${value.id}" includes a flow while state is "${value.state}".`);
|
|
167
|
-
}
|
|
168
|
-
return {
|
|
169
|
-
id: value.id,
|
|
170
|
-
...(value.displayName ? { displayName: boundedAuthText(value.displayName, "Auth provider display name", 160) } : {}),
|
|
171
|
-
state: value.state,
|
|
172
|
-
configured: value.configured,
|
|
173
|
-
methods,
|
|
174
|
-
...(value.pending ? { pending: cloneAuthFlow(value.pending, declaredMethods) } : {}),
|
|
175
|
-
...(value.message ? { message: boundedAuthText(value.message, "Auth status message", 1_000) } : {}),
|
|
176
|
-
...(value.details ? { details: cloneAuthDetails(value.details) } : {}),
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
function cloneAuthOperationResult(value, inputProviderId, declaredMethods) {
|
|
180
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
181
|
-
throw new AgentRuntimeContractError("auth", "Auth operation result must be an object.");
|
|
182
|
-
}
|
|
183
|
-
assertAuthId(value.providerId, "Auth result provider id");
|
|
184
|
-
if (value.providerId !== inputProviderId) {
|
|
185
|
-
throw new AgentRuntimeContractError("auth", `Auth result provider "${value.providerId}" does not match requested provider "${inputProviderId}".`);
|
|
186
|
-
}
|
|
187
|
-
if (!AUTH_STATES.has(value.state)) {
|
|
188
|
-
throw new AgentRuntimeContractError("auth", `Auth result reported invalid state "${String(value.state)}".`);
|
|
189
|
-
}
|
|
190
|
-
if (typeof value.configured !== "boolean") {
|
|
191
|
-
throw new AgentRuntimeContractError("auth", "Auth result configured must be a boolean.");
|
|
192
|
-
}
|
|
193
|
-
validateAuthConfiguredState(value.state, value.configured);
|
|
194
|
-
if (value.state === "pending" && !value.flow) {
|
|
195
|
-
throw new AgentRuntimeContractError("auth", "Pending auth result must include a flow.");
|
|
196
|
-
}
|
|
197
|
-
if (value.state !== "pending" && value.flow) {
|
|
198
|
-
throw new AgentRuntimeContractError("auth", `Auth result includes a flow while state is "${value.state}".`);
|
|
199
|
-
}
|
|
200
|
-
return {
|
|
201
|
-
providerId: value.providerId,
|
|
202
|
-
state: value.state,
|
|
203
|
-
configured: value.configured,
|
|
204
|
-
...(value.flow ? { flow: cloneAuthFlow(value.flow, declaredMethods) } : {}),
|
|
205
|
-
...(value.message ? { message: boundedAuthText(value.message, "Auth result message", 1_000) } : {}),
|
|
206
|
-
...(value.details ? { details: cloneAuthDetails(value.details) } : {}),
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
function assertAdapterAuthContract(adapter) {
|
|
210
|
-
const auth = adapter.descriptor.capabilities.auth;
|
|
211
|
-
if (auth.status !== Boolean(adapter.getAuthStatus)) {
|
|
212
|
-
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" auth.status must match getAuthStatus().`);
|
|
213
|
-
}
|
|
214
|
-
if ((auth.methods.length > 0) !== Boolean(adapter.startAuth)) {
|
|
215
|
-
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" declared auth methods must match startAuth().`);
|
|
216
|
-
}
|
|
217
|
-
const needsCompletion = auth.methods.some((method) => method.completion !== "immediate");
|
|
218
|
-
if (needsCompletion !== Boolean(adapter.completeAuth)) {
|
|
219
|
-
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" non-immediate auth methods must match completeAuth().`);
|
|
220
|
-
}
|
|
221
|
-
if (needsCompletion && !adapter.disposeAuth) {
|
|
222
|
-
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" non-immediate auth methods require disposeAuth().`);
|
|
223
|
-
}
|
|
224
|
-
if (auth.cancel !== Boolean(adapter.cancelAuth)) {
|
|
225
|
-
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" auth.cancel must match cancelAuth().`);
|
|
226
|
-
}
|
|
227
|
-
if (auth.logout !== Boolean(adapter.logoutAuth)) {
|
|
228
|
-
throw new AgentRuntimeRegistrationError(`Agent runtime instance "${adapter.instanceId}" auth.logout must match logoutAuth().`);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
18
|
export class AgentRuntimeAdapterRegistry {
|
|
232
19
|
drivers = new Map();
|
|
233
20
|
instances = new Map();
|
|
@@ -258,6 +258,7 @@ export class RuntimeRoutedSession {
|
|
|
258
258
|
activeEventId: activeMessage.id,
|
|
259
259
|
text: event.text,
|
|
260
260
|
source: event.source,
|
|
261
|
+
provenance: event.provenance,
|
|
261
262
|
};
|
|
262
263
|
this.emit(output);
|
|
263
264
|
return output;
|
|
@@ -327,6 +328,12 @@ export class RuntimeRoutedSession {
|
|
|
327
328
|
provenance: this.activeMessage.provenance,
|
|
328
329
|
};
|
|
329
330
|
}
|
|
331
|
+
canSteerMessage() {
|
|
332
|
+
return Boolean(this.activeMessage
|
|
333
|
+
&& this.processing
|
|
334
|
+
&& this.runtimeSession.getStatus().streaming
|
|
335
|
+
&& this.runtimeSession.steer);
|
|
336
|
+
}
|
|
330
337
|
getStatus() {
|
|
331
338
|
const status = this.runtimeSession.getStatus();
|
|
332
339
|
const binding = this.runtimeSession.getBinding();
|
|
@@ -171,7 +171,7 @@ function toolDescriptor(item) {
|
|
|
171
171
|
return { name: "codex_web_search", args: redactCodexNativeValue({ query: item.query, action: item.action }) };
|
|
172
172
|
}
|
|
173
173
|
if (item.type === "imageView") {
|
|
174
|
-
return { name: "codex_image_view", args: {
|
|
174
|
+
return { name: "codex_image_view", args: redactCodexNativeValue({ path: item.path }) };
|
|
175
175
|
}
|
|
176
176
|
if (item.type === "sleep") {
|
|
177
177
|
return { name: "codex_sleep", args: redactCodexNativeValue({ durationMs: item.durationMs }) };
|
|
@@ -204,7 +204,7 @@ function toolResult(item) {
|
|
|
204
204
|
if (item.type === "webSearch")
|
|
205
205
|
return redactCodexNativeValue({ query: item.query, results: item.results });
|
|
206
206
|
if (item.type === "imageView")
|
|
207
|
-
return { status: item.status ?? "completed",
|
|
207
|
+
return redactCodexNativeValue({ status: item.status ?? "completed", path: item.path });
|
|
208
208
|
if (item.type === "sleep")
|
|
209
209
|
return redactCodexNativeValue({ status: item.status, durationMs: item.durationMs });
|
|
210
210
|
if (item.type === "imageGeneration") {
|
|
@@ -263,6 +263,7 @@ const PI_API_KEY_PROVIDERS = new Set([
|
|
|
263
263
|
"minimax",
|
|
264
264
|
"minimax-cn",
|
|
265
265
|
"glm",
|
|
266
|
+
"meta-muse",
|
|
266
267
|
]);
|
|
267
268
|
const PI_DEVICE_METHOD = { id: "device_code", completion: "explicit" };
|
|
268
269
|
const PI_BROWSER_METHOD = { id: "browser_oauth", completion: "explicit" };
|
|
@@ -2,6 +2,7 @@ import { ModelRegistry, createAgentSessionServices, } from "@earendil-works/pi-c
|
|
|
2
2
|
import { registerMiniMaxProvider } from "../../providers/minimax.js";
|
|
3
3
|
import { registerGlmProvider } from "../../providers/glm.js";
|
|
4
4
|
import { registerQwenTokenPlanProvider } from "../../providers/qwen-token-plan.js";
|
|
5
|
+
import { registerMetaMuseProvider } from "../../providers/meta-muse.js";
|
|
5
6
|
import { registerOpenAiSupplementalModels } from "../../providers/openai-gpt56.js";
|
|
6
7
|
import { piAuthMethodsForProvider } from "./auth.js";
|
|
7
8
|
export function buildModelCatalogFromRegistry(registry) {
|
|
@@ -56,6 +57,7 @@ export async function loadModelCatalog(cwd = process.cwd()) {
|
|
|
56
57
|
registerMiniMaxProvider(registry);
|
|
57
58
|
registerGlmProvider(registry);
|
|
58
59
|
registerQwenTokenPlanProvider(registry);
|
|
60
|
+
registerMetaMuseProvider(registry);
|
|
59
61
|
});
|
|
60
62
|
}
|
|
61
63
|
export function piAgentRuntimeModelCatalog(runtimeInstanceId, catalog) {
|
|
@@ -21,6 +21,7 @@ import { DEFAULT_USER_TIMEZONE } from "../../core/user-settings.js";
|
|
|
21
21
|
import { registerMiniMaxProvider } from "../../providers/minimax.js";
|
|
22
22
|
import { registerGlmProvider } from "../../providers/glm.js";
|
|
23
23
|
import { registerQwenTokenPlanProvider } from "../../providers/qwen-token-plan.js";
|
|
24
|
+
import { registerMetaMuseProvider } from "../../providers/meta-muse.js";
|
|
24
25
|
import { registerOpenAiSupplementalModels } from "../../providers/openai-gpt56.js";
|
|
25
26
|
import { PIBO_APP_CONTEXT } from "../../app-context.js";
|
|
26
27
|
import { RuntimeSessionRegistry } from "../../tools/runtime/registry.js";
|
|
@@ -260,6 +261,7 @@ export async function createPiboRuntime(options = {}) {
|
|
|
260
261
|
registerMiniMaxProvider(modelRegistry);
|
|
261
262
|
registerGlmProvider(modelRegistry);
|
|
262
263
|
registerQwenTokenPlanProvider(modelRegistry);
|
|
264
|
+
registerMetaMuseProvider(modelRegistry);
|
|
263
265
|
const ownsLocalRuntimeRegistry = options.runtimeToolController === undefined && profile.tools.some(isEnabledRuntimeTool);
|
|
264
266
|
const localRuntimeRegistry = ownsLocalRuntimeRegistry ? new RuntimeSessionRegistry({ cwd: runtimeCwd }) : undefined;
|
|
265
267
|
const runtimeToolController = options.runtimeToolController
|
|
@@ -254,6 +254,7 @@ function compactTraceNode(node, payloadStore, piboSessionId, depth) {
|
|
|
254
254
|
toolMetrics: node.toolMetrics,
|
|
255
255
|
modelInferences: node.modelInferences,
|
|
256
256
|
compactionStats: node.compactionStats,
|
|
257
|
+
fileAttachments: node.fileAttachments,
|
|
257
258
|
orderKey: node.orderKey,
|
|
258
259
|
depth,
|
|
259
260
|
hasChildren: node.children.length > 0,
|
|
@@ -3648,6 +3648,7 @@ async function sendChatMessage(input) {
|
|
|
3648
3648
|
piboSessionId: selectedSession.id,
|
|
3649
3649
|
roomId: room.id,
|
|
3650
3650
|
text: fileAttachmentContext.messageText,
|
|
3651
|
+
userText: text,
|
|
3651
3652
|
delivery,
|
|
3652
3653
|
...(webAnnotationContext.attachments.length ? {
|
|
3653
3654
|
webAnnotationIds: webAnnotationContext.ids,
|