arisa 5.2.17 → 5.2.19
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/README.md +4 -2
- package/package.json +10 -9
- package/pnpm-workspace.yaml +7 -5
- package/src/core/agent/agent-manager.js +13 -14
- package/src/core/agent/auth-flow.js +6 -6
- package/src/core/agent/model-speed.js +3 -1
- package/src/core/agent/pi-auth-login.js +28 -28
- package/src/core/agent/pi-capability-tools.js +1 -0
- package/src/core/agent/pi-runtime.js +14 -21
- package/src/core/capabilities/capability-service.js +25 -0
- package/src/core/tasks/task-store.js +2 -1
- package/src/official-tools.lock.json +25 -18
- package/src/runtime/bootstrap-cli.js +3 -3
- package/src/runtime/bootstrap-telegram.js +7 -7
- package/src/runtime/slave-cli.js +20 -10
- package/src/runtime/slave-service.js +299 -7
- package/src/runtime/tui.js +5 -6
- package/src/transport/telegram/bot.js +9 -5
- package/src/transport/telegram/model-controls.js +1 -1
- package/src/transport/telegram/task-dispatcher.js +50 -23
- package/src/transport/telegram/telegram-auth-controller.js +7 -7
- package/src/transport/telegram/telegram-session-bridge.js +2 -1
- package/test/agent-turn-coordinator.test.js +5 -2
- package/test/auth-flow.test.js +2 -2
- package/test/capabilities-security.test.js +36 -0
- package/test/model-selection.test.js +3 -2
- package/test/official-tool-installer.test.js +13 -0
- package/test/pi-auth-login.test.js +78 -0
- package/test/pi-capability-tools.test.js +3 -0
- package/test/pi-speed-integration.test.js +176 -0
- package/test/slave-cli.test.js +221 -5
- package/test/task-store.test.js +3 -1
- package/test/telegram-task-dispatcher.test.js +57 -2
package/README.md
CHANGED
|
@@ -127,8 +127,10 @@ Slave runs only the IPC host, daemon supervisor and installed tools. Connections
|
|
|
127
127
|
are authenticated, encrypted, initiated by Slave and restricted by per-Slave
|
|
128
128
|
roots and capability grants.
|
|
129
129
|
|
|
130
|
-
Linux with systemd
|
|
131
|
-
|
|
130
|
+
Arisa Slave supports Linux with systemd, macOS with launchd, and Windows with
|
|
131
|
+
Task Scheduler. On desktop systems, run bootstrap as the normal user so the
|
|
132
|
+
persistent background task retains access to that user's browser profile.
|
|
133
|
+
Bootstrap uses a single-use URL issued by Master:
|
|
132
134
|
|
|
133
135
|
```bash
|
|
134
136
|
npm i -g arisa && arisa slave tcp://198.51.100.12:4719/arisa_secret_v1_<secret>
|
package/package.json
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arisa",
|
|
3
|
-
"version": "5.2.
|
|
3
|
+
"version": "5.2.19",
|
|
4
4
|
"description": "Telegram + Pi Agent modular assistant",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"arisa": "bin/arisa.js"
|
|
9
9
|
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node src/index.js",
|
|
12
|
+
"bootstrap": "node src/index.js --bootstrap",
|
|
13
|
+
"test": "node --test"
|
|
14
|
+
},
|
|
10
15
|
"keywords": [
|
|
11
16
|
"telegram",
|
|
12
17
|
"pi-agent",
|
|
@@ -29,7 +34,7 @@
|
|
|
29
34
|
"author": "Martin Clasen",
|
|
30
35
|
"license": "MIT",
|
|
31
36
|
"engines": {
|
|
32
|
-
"node": ">=22.
|
|
37
|
+
"node": ">=22.19.0"
|
|
33
38
|
},
|
|
34
39
|
"repository": {
|
|
35
40
|
"type": "git",
|
|
@@ -39,14 +44,10 @@
|
|
|
39
44
|
"url": "https://github.com/clasen/Arisa/issues"
|
|
40
45
|
},
|
|
41
46
|
"homepage": "https://arisa.sh",
|
|
47
|
+
"packageManager": "pnpm@11.3.0+sha512.2c403d6594527287672b1f7056343a1f7c3634036a67ffabfcc2b3d7595d843768f8787148d1b57cf7956c90606bbd192857c363af19e96d2d0ec9ec5741d215",
|
|
42
48
|
"dependencies": {
|
|
43
|
-
"@earendil-works/pi-coding-agent": "0.
|
|
49
|
+
"@earendil-works/pi-coding-agent": "0.85.1",
|
|
44
50
|
"@sinclair/typebox": "^0.34.41",
|
|
45
51
|
"grammy": "^1.42.0"
|
|
46
|
-
},
|
|
47
|
-
"scripts": {
|
|
48
|
-
"start": "node src/index.js",
|
|
49
|
-
"bootstrap": "node src/index.js --bootstrap",
|
|
50
|
-
"test": "node --test"
|
|
51
52
|
}
|
|
52
|
-
}
|
|
53
|
+
}
|
package/pnpm-workspace.yaml
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
allowBuilds:
|
|
2
2
|
'@google/genai': false
|
|
3
|
+
esbuild: true
|
|
3
4
|
|
|
4
5
|
minimumReleaseAgeExclude:
|
|
5
|
-
- '@earendil-works/pi-agent-core@0.
|
|
6
|
-
- '@earendil-works/pi-ai@0.
|
|
7
|
-
- '@earendil-works/pi-coding-agent@0.
|
|
8
|
-
- '@earendil-works/pi-tui@0.
|
|
6
|
+
- '@earendil-works/pi-agent-core@0.85.1'
|
|
7
|
+
- '@earendil-works/pi-ai@0.85.1'
|
|
8
|
+
- '@earendil-works/pi-coding-agent@0.85.1'
|
|
9
|
+
- '@earendil-works/pi-tui@0.85.1'
|
|
10
|
+
- '@earendil-works/chord@0.85.1'
|
|
9
11
|
|
|
10
12
|
overrides:
|
|
11
13
|
'node-fetch@2.7.0>whatwg-url': '13.0.0'
|
|
@@ -14,7 +16,7 @@ overrides:
|
|
|
14
16
|
basic-ftp@<=5.2.2: '>=5.3.0'
|
|
15
17
|
basic-ftp@<=5.3.0: '>=5.3.1'
|
|
16
18
|
basic-ftp@=5.2.0: '>=5.2.1'
|
|
17
|
-
brace-expansion@>=
|
|
19
|
+
brace-expansion@>=4.0.0 <5.0.9: '5.0.9'
|
|
18
20
|
ip-address@<=10.1.0: '>=10.1.1'
|
|
19
21
|
protobufjs@<7.5.5: '>=7.5.5'
|
|
20
22
|
protobufjs@<=7.5.5: '>=7.5.6'
|
|
@@ -323,22 +323,21 @@ export class AgentManager {
|
|
|
323
323
|
|
|
324
324
|
async validatePiAgent(config = this.config) {
|
|
325
325
|
this.logger?.log("agent", "validating Pi session");
|
|
326
|
-
const
|
|
326
|
+
const modelRuntime = await createPiRuntime({
|
|
327
327
|
provider: config.pi.provider,
|
|
328
328
|
apiKey: config.pi.apiKey
|
|
329
329
|
});
|
|
330
|
-
const model =
|
|
330
|
+
const model = modelRuntime.getModel(config.pi.provider, config.pi.model);
|
|
331
331
|
if (!model) {
|
|
332
332
|
throw new Error(`Model not found: ${config.pi.provider}/${config.pi.model}`);
|
|
333
333
|
}
|
|
334
|
-
if (requiresProviderAuth(model) && !config.pi.apiKey && !hasProviderAuth(config.pi.provider,
|
|
334
|
+
if (requiresProviderAuth(model) && !config.pi.apiKey && !hasProviderAuth(config.pi.provider, modelRuntime)) {
|
|
335
335
|
throw new Error(`No auth found for ${config.pi.provider}. Provide a Pi API key in bootstrap, or authenticate with Pi login for this provider during bootstrap.`);
|
|
336
336
|
}
|
|
337
337
|
|
|
338
338
|
const settingsManager = createPiSettingsManager(config);
|
|
339
339
|
const { session } = await createAgentSession({
|
|
340
|
-
|
|
341
|
-
modelRegistry,
|
|
340
|
+
modelRuntime,
|
|
342
341
|
model,
|
|
343
342
|
settingsManager,
|
|
344
343
|
sessionManager: SessionManager.inMemory()
|
|
@@ -386,13 +385,13 @@ export class AgentManager {
|
|
|
386
385
|
this.pendingNewSessions.add(sessionKey);
|
|
387
386
|
}
|
|
388
387
|
|
|
389
|
-
const
|
|
388
|
+
const modelRuntime = await createPiRuntime({
|
|
390
389
|
provider: this.config.pi.provider,
|
|
391
390
|
apiKey: this.config.pi.apiKey
|
|
392
391
|
});
|
|
393
|
-
const model =
|
|
392
|
+
const model = modelRuntime.getModel(this.config.pi.provider, effectiveModelId);
|
|
394
393
|
if (!model) throw new Error(`Model not found: ${this.config.pi.provider}/${effectiveModelId}`);
|
|
395
|
-
if (requiresProviderAuth(model) && !this.config.pi.apiKey && !hasProviderAuth(this.config.pi.provider,
|
|
394
|
+
if (requiresProviderAuth(model) && !this.config.pi.apiKey && !hasProviderAuth(this.config.pi.provider, modelRuntime)) {
|
|
396
395
|
throw new Error(`No auth found for ${this.config.pi.provider}. Re-run bootstrap and complete login for this provider before Telegram starts.`);
|
|
397
396
|
}
|
|
398
397
|
const thinkingLevel = clampModelThinkingLevel(model, modelSelection.thinkingLevel);
|
|
@@ -418,7 +417,8 @@ export class AgentManager {
|
|
|
418
417
|
initializeForumTopic: (...args) => telegramTarget.current.initializeForumTopic(...args),
|
|
419
418
|
prepareRestartReceipt: (...args) => telegramTarget.current.prepareRestartReceipt(...args),
|
|
420
419
|
cancelRestartReceipt: (...args) => telegramTarget.current.cancelRestartReceipt(...args),
|
|
421
|
-
getTaskContext: (...args) => telegramTarget.current.getTaskContext?.(...args) || null
|
|
420
|
+
getTaskContext: (...args) => telegramTarget.current.getTaskContext?.(...args) || null,
|
|
421
|
+
getAgentTaskExecution: (...args) => telegramTarget.current.getAgentTaskExecution?.(...args) || null
|
|
422
422
|
};
|
|
423
423
|
const assertAccess = () => accessGuardTarget.current();
|
|
424
424
|
const customTools = guardTools([
|
|
@@ -440,8 +440,7 @@ export class AgentManager {
|
|
|
440
440
|
cwd: policy.workspaceDir,
|
|
441
441
|
agentDir: arisaHomeDir,
|
|
442
442
|
resourceLoader,
|
|
443
|
-
|
|
444
|
-
modelRegistry,
|
|
443
|
+
modelRuntime,
|
|
445
444
|
model,
|
|
446
445
|
thinkingLevel,
|
|
447
446
|
tools: policy.tools,
|
|
@@ -450,8 +449,8 @@ export class AgentManager {
|
|
|
450
449
|
settingsManager,
|
|
451
450
|
sessionManager
|
|
452
451
|
});
|
|
453
|
-
const speedController = createModelSpeedController(session.agent.
|
|
454
|
-
session.agent.
|
|
452
|
+
const speedController = createModelSpeedController(session.agent.streamFunction, speed);
|
|
453
|
+
session.agent.streamFunction = speedController.streamFn;
|
|
455
454
|
|
|
456
455
|
if (!hasExistingSession) {
|
|
457
456
|
this.logger?.log("agent", `created new session for chat ${sessionKey}`);
|
|
@@ -479,7 +478,7 @@ export class AgentManager {
|
|
|
479
478
|
|
|
480
479
|
async getAvailableModels(chatId) {
|
|
481
480
|
const { listProviderModels } = await import("./pi-runtime.js");
|
|
482
|
-
const runtime = createPiRuntime({ provider: this.config.pi.provider, apiKey: this.config.pi.apiKey });
|
|
481
|
+
const runtime = await createPiRuntime({ provider: this.config.pi.provider, apiKey: this.config.pi.apiKey });
|
|
483
482
|
return listProviderModels(this.config.pi.provider, runtime);
|
|
484
483
|
}
|
|
485
484
|
|
|
@@ -33,8 +33,8 @@ export function getPiAuthIssue(error) {
|
|
|
33
33
|
return null;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export function getPiAuthStatus(config, chatId = null) {
|
|
37
|
-
const runtime = createPiRuntime({
|
|
36
|
+
export async function getPiAuthStatus(config, chatId = null) {
|
|
37
|
+
const runtime = await createPiRuntime({
|
|
38
38
|
provider: config.pi.provider,
|
|
39
39
|
apiKey: config.pi.apiKey
|
|
40
40
|
});
|
|
@@ -51,8 +51,8 @@ export function getPiAuthStatus(config, chatId = null) {
|
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
export function buildPiAuthTelegramMessage({ config, chatId = null, issue = null, verified = false }) {
|
|
55
|
-
const status = getPiAuthStatus(config, chatId);
|
|
54
|
+
export async function buildPiAuthTelegramMessage({ config, chatId = null, issue = null, verified = false }) {
|
|
55
|
+
const status = await getPiAuthStatus(config, chatId);
|
|
56
56
|
let title = `Pi authentication status for ${status.provider}/${status.model}.`;
|
|
57
57
|
if (issue) {
|
|
58
58
|
title = `Pi authentication needs attention for ${status.provider}/${status.model}.`;
|
|
@@ -95,8 +95,8 @@ export function buildPiAuthTelegramMessage({ config, chatId = null, issue = null
|
|
|
95
95
|
return lines.join("\n");
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
export function buildPiAuthRecoveryBlockedMessage({ config, chatId = null, issue = null, renewalActive = false }) {
|
|
99
|
-
const status = getPiAuthStatus(config, chatId);
|
|
98
|
+
export async function buildPiAuthRecoveryBlockedMessage({ config, chatId = null, issue = null, renewalActive = false }) {
|
|
99
|
+
const status = await getPiAuthStatus(config, chatId);
|
|
100
100
|
const lines = [
|
|
101
101
|
`Pi authentication is not ready for ${status.provider}/${status.model}.`,
|
|
102
102
|
"I did not send your message to the agent."
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
export const MODEL_SPEEDS = Object.freeze([1, 1.5]);
|
|
2
2
|
|
|
3
3
|
export function normalizeModelSpeed(speed) {
|
|
4
4
|
const value = Number(speed);
|
|
@@ -17,6 +17,7 @@ export function modelSupportsSpeed(model) {
|
|
|
17
17
|
|| model.id === "gpt-5.5"
|
|
18
18
|
|| model.id === "gpt-5.6"
|
|
19
19
|
|| model.id.startsWith("gpt-5.6-")
|
|
20
|
+
|| model.id === "gpt-6-astra"
|
|
20
21
|
);
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -40,6 +41,7 @@ export function createModelSpeedController(streamFn, initialSpeed) {
|
|
|
40
41
|
speed = normalizeModelSpeed(nextSpeed);
|
|
41
42
|
},
|
|
42
43
|
streamFn(model, context, options) {
|
|
44
|
+
if (!modelSupportsSpeed(model)) return streamFn(model, context, options);
|
|
43
45
|
const serviceTier = speedToServiceTier(speed);
|
|
44
46
|
const onPayload = options?.onPayload;
|
|
45
47
|
return streamFn(model, context, {
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { piAuthFile } from "../../platform/paths.js";
|
|
1
|
+
import { createPiRuntime, supportsProviderOAuth } from "./pi-runtime.js";
|
|
3
2
|
|
|
4
3
|
export function createPiOAuthLogin({ provider, onAuth, onDeviceCode, onPrompt, onProgress, onSelect } = {}) {
|
|
5
|
-
const authStorage = AuthStorage.create(piAuthFile);
|
|
6
|
-
const oauthProvider = authStorage.getOAuthProviders().find((item) => item.id === provider);
|
|
7
|
-
if (!oauthProvider) {
|
|
8
|
-
throw new Error(`No internal OAuth login flow is available for ${provider}.`);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
4
|
let resolveManualCode;
|
|
12
5
|
const manualCodePromise = new Promise((resolve) => {
|
|
13
6
|
resolveManualCode = resolve;
|
|
@@ -15,7 +8,6 @@ export function createPiOAuthLogin({ provider, onAuth, onDeviceCode, onPrompt, o
|
|
|
15
8
|
|
|
16
9
|
const controller = {
|
|
17
10
|
provider,
|
|
18
|
-
oauthProvider,
|
|
19
11
|
manualInputRequested: false,
|
|
20
12
|
submitManualCode(value) {
|
|
21
13
|
if (!resolveManualCode) return false;
|
|
@@ -31,25 +23,33 @@ export function createPiOAuthLogin({ provider, onAuth, onDeviceCode, onPrompt, o
|
|
|
31
23
|
promise: null
|
|
32
24
|
};
|
|
33
25
|
|
|
34
|
-
controller.promise =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
26
|
+
controller.promise = createPiRuntime().then(async (runtime) => {
|
|
27
|
+
if (!supportsProviderOAuth(provider, runtime)) {
|
|
28
|
+
throw new Error(`No internal OAuth login flow is available for ${provider}.`);
|
|
29
|
+
}
|
|
30
|
+
let notifications = Promise.resolve();
|
|
31
|
+
let notificationError;
|
|
32
|
+
const credential = await runtime.login(provider, "oauth", {
|
|
33
|
+
notify(event) {
|
|
34
|
+
notifications = notifications.then(async () => {
|
|
35
|
+
if (event.type === "auth_url") await onAuth?.({ ...event, controller });
|
|
36
|
+
else if (event.type === "device_code") await onDeviceCode?.({ ...event, controller });
|
|
37
|
+
else await onProgress?.(event.message);
|
|
38
|
+
}).catch((error) => { notificationError = error; });
|
|
39
|
+
},
|
|
40
|
+
async prompt(params) {
|
|
41
|
+
await notifications;
|
|
42
|
+
if (notificationError) throw notificationError;
|
|
43
|
+
if (params.type === "select") {
|
|
44
|
+
return onSelect ? onSelect({ ...params, controller }) : params.options?.[0]?.id;
|
|
45
|
+
}
|
|
46
|
+
if (params.type === "manual_code") return controller.waitForManualCode();
|
|
47
|
+
return onPrompt ? onPrompt({ ...params, controller }) : "";
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
await notifications;
|
|
51
|
+
if (notificationError) throw notificationError;
|
|
52
|
+
return credential;
|
|
53
53
|
}).finally(() => {
|
|
54
54
|
controller.submitManualCode("");
|
|
55
55
|
});
|
|
@@ -1,34 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ModelRuntime } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { piAuthFile } from "../../platform/paths.js";
|
|
3
3
|
|
|
4
4
|
function compareText(a, b) {
|
|
5
5
|
return a.localeCompare(b, undefined, { sensitivity: "base", numeric: true });
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
export function createPiRuntime({ provider, apiKey } = {}) {
|
|
9
|
-
const
|
|
8
|
+
export async function createPiRuntime({ provider, apiKey } = {}) {
|
|
9
|
+
const runtime = await ModelRuntime.create({ authPath: piAuthFile });
|
|
10
10
|
if (provider && apiKey) {
|
|
11
|
-
|
|
11
|
+
await runtime.setRuntimeApiKey(provider, apiKey);
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
const oauthProviders = authStorage.getOAuthProviders();
|
|
15
|
-
return { authStorage, modelRegistry, oauthProviders };
|
|
13
|
+
return runtime;
|
|
16
14
|
}
|
|
17
15
|
|
|
18
|
-
export function hasProviderAuth(provider,
|
|
19
|
-
return
|
|
16
|
+
export function hasProviderAuth(provider, runtime) {
|
|
17
|
+
return runtime.getProviderAuthStatus(provider).configured;
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
export function supportsProviderOAuth(provider,
|
|
23
|
-
return
|
|
20
|
+
export function supportsProviderOAuth(provider, runtime) {
|
|
21
|
+
return Boolean(runtime.getProvider(provider)?.auth.oauth);
|
|
24
22
|
}
|
|
25
23
|
|
|
26
|
-
export function listPiProviders(runtime
|
|
27
|
-
const { modelRegistry, oauthProviders } = runtime;
|
|
28
|
-
const allModels = modelRegistry.getAll();
|
|
29
|
-
const oauthIds = new Set(oauthProviders.map((item) => item.id));
|
|
24
|
+
export function listPiProviders(runtime) {
|
|
30
25
|
const counts = new Map();
|
|
31
|
-
for (const model of
|
|
26
|
+
for (const model of runtime.getModels()) {
|
|
32
27
|
counts.set(model.provider, (counts.get(model.provider) || 0) + 1);
|
|
33
28
|
}
|
|
34
29
|
|
|
@@ -36,7 +31,7 @@ export function listPiProviders(runtime = createPiRuntime()) {
|
|
|
36
31
|
.map((provider) => ({
|
|
37
32
|
provider,
|
|
38
33
|
authConfigured: hasProviderAuth(provider, runtime),
|
|
39
|
-
supportsOAuth:
|
|
34
|
+
supportsOAuth: supportsProviderOAuth(provider, runtime),
|
|
40
35
|
modelCount: counts.get(provider) || 0
|
|
41
36
|
}))
|
|
42
37
|
.sort((a, b) => {
|
|
@@ -46,10 +41,8 @@ export function listPiProviders(runtime = createPiRuntime()) {
|
|
|
46
41
|
});
|
|
47
42
|
}
|
|
48
43
|
|
|
49
|
-
export function listProviderModels(provider, runtime
|
|
50
|
-
return runtime.
|
|
51
|
-
.getAll()
|
|
52
|
-
.filter((model) => model.provider === provider)
|
|
44
|
+
export function listProviderModels(provider, runtime) {
|
|
45
|
+
return [...runtime.getModels(provider)]
|
|
53
46
|
.sort((a, b) => compareText(a.name || a.id, b.name || b.id));
|
|
54
47
|
}
|
|
55
48
|
|
|
@@ -48,6 +48,17 @@ function normalizeAcknowledgement(value) {
|
|
|
48
48
|
return acknowledgement;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
function recordAgentTaskAuthBlock(execution, toolName, result) {
|
|
52
|
+
if (!execution || execution.blockedAuth || result?.ok !== false || result?.status !== "blocked_auth") return;
|
|
53
|
+
execution.blockedAuth = {
|
|
54
|
+
toolName,
|
|
55
|
+
error: String(result.error || `${toolName} authentication is required`).slice(0, 1_000),
|
|
56
|
+
resolution: result.resolution && typeof result.resolution === "object"
|
|
57
|
+
? structuredClone(result.resolution)
|
|
58
|
+
: {}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
51
62
|
function inferDeliveryMethod(artifact) {
|
|
52
63
|
if (artifact.kind === "audio" || (artifact.mimeType || "").startsWith("audio/")) return "audio";
|
|
53
64
|
if (artifact.kind === "image" || (artifact.mimeType || "").startsWith("image/")) return "photo";
|
|
@@ -178,6 +189,19 @@ export function createCapabilityService({
|
|
|
178
189
|
if (!toolExecutor?.runTool) throw new Error("tools.run requires toolExecutor");
|
|
179
190
|
const scopedChatId = requireChatId(chatId, method);
|
|
180
191
|
const targetToolName = requireString(params.name, "name");
|
|
192
|
+
const blocked = context.agentTaskExecution?.blockedAuth;
|
|
193
|
+
if (blocked) {
|
|
194
|
+
return {
|
|
195
|
+
ok: false,
|
|
196
|
+
status: "blocked_prerequisite",
|
|
197
|
+
error: `Authentication for ${blocked.toolName} is blocking this scheduled task.`,
|
|
198
|
+
resolution: {
|
|
199
|
+
type: "blocked_prerequisite",
|
|
200
|
+
prerequisiteStatus: "blocked_auth",
|
|
201
|
+
toolName: blocked.toolName
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
181
205
|
const chatArtifactStore = artifactStore.forChat(scopedChatId);
|
|
182
206
|
const artifact = params.artifactId
|
|
183
207
|
? await chatArtifactStore.get(requireString(params.artifactId, "artifactId"))
|
|
@@ -197,6 +221,7 @@ export function createCapabilityService({
|
|
|
197
221
|
chatId: scopedChatId,
|
|
198
222
|
taskContext: context.taskContext || null
|
|
199
223
|
});
|
|
224
|
+
recordAgentTaskAuthBlock(context.agentTaskExecution, targetToolName, result);
|
|
200
225
|
if (params.deliver && result.output?.artifactId) {
|
|
201
226
|
const generated = await chatArtifactStore.get(result.output.artifactId);
|
|
202
227
|
if (generated?.path) {
|
|
@@ -177,7 +177,8 @@ function normalizeAuthResolution(resolution = {}) {
|
|
|
177
177
|
? structuredClone(value.probeArgs)
|
|
178
178
|
: {};
|
|
179
179
|
if (JSON.stringify(probeArgs).length > 4_096) throw new Error("Authentication probe arguments are too large");
|
|
180
|
-
|
|
180
|
+
const toolName = typeof value.toolName === "string" ? value.toolName.trim().slice(0, 128) : "";
|
|
181
|
+
return { retryAfterSeconds, probeArgs, ...(toolName ? { toolName } : {}) };
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
function failTask(task, error) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
3
|
"repository": "https://github.com/clasen/Arisa.git",
|
|
4
|
-
"commit": "
|
|
4
|
+
"commit": "2256f9e19f26f23826b9a9062d3a9643b511bb3c",
|
|
5
5
|
"tools": {
|
|
6
6
|
"audio-extractor": {
|
|
7
7
|
"version": null,
|
|
@@ -13,10 +13,11 @@
|
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"browser-session-bridge": {
|
|
16
|
-
"version": "0.2.
|
|
16
|
+
"version": "0.2.5",
|
|
17
17
|
"files": {
|
|
18
|
-
"
|
|
19
|
-
"
|
|
18
|
+
"README.md": "79cb347ead539309429eca19ba6e9c472e4790ec1ab39a20bba71a4149f61f15",
|
|
19
|
+
"bridge-server.js": "03722a2657ba74bf34de9cae683b8f23242657da87c05771dd413a38fb446eca",
|
|
20
|
+
"chrome-web-store.js": "4b588d1288dee754c5d8afd609b8c1f67f73d23de7dda247b7a2ff8b68f7ef60",
|
|
20
21
|
"config.js": "45c8e9e9a159b9125d6ea3458c616926c2ba2b5327fdfd750aa05316d3ce5af8",
|
|
21
22
|
"extension/icons/icon-128.png": "a55af49bb570bd5471fc0a2e15a6bcaf3f76a2c5e7439f16bb1829682b343380",
|
|
22
23
|
"extension/icons/icon-16.png": "a4aedb49e2227222a68dc56455812a9e17938fd197b1f30268f02d6c9f7bf95e",
|
|
@@ -31,24 +32,26 @@
|
|
|
31
32
|
"extension/site-permissions.js": "83f9aa4d0295318fc730bd561c2db9d1aacf36152319090e99d12f62deea11ad",
|
|
32
33
|
"index.js": "c01a6b825da4587a550ecec560a558cc6736200e73b6831f5919000c7b81679d",
|
|
33
34
|
"lightpanda-session.js": "57c713dafac531617d7285122b2098c1e0b2f334e43144632f2b1fc79405f789",
|
|
34
|
-
"package-lock.json": "
|
|
35
|
-
"package.json": "
|
|
36
|
-
"README.md": "79cb347ead539309429eca19ba6e9c472e4790ec1ab39a20bba71a4149f61f15",
|
|
35
|
+
"package-lock.json": "b97f5a333df234fecde788d0f90b620d39e02fee6079c1b4347baaabd8010b1b",
|
|
36
|
+
"package.json": "5c9edd6155b6b4868cc87d474e808dfc23567bc312e0d1e0230d8f9f0a1cc081",
|
|
37
37
|
"session-browser.js": "7af716a1c0d6793b82ebbaaf64ec3e8f73dfc52b3c9aceef2179d2d859e32a9c",
|
|
38
38
|
"session-redaction.js": "c2393023c1d3b7634432606ad82a96d79c1f093d9b0a6440d955d0ae419c8393",
|
|
39
39
|
"session-selection.js": "da5a4f55ccc8ba22791840943288e7aecacd730425c03f05c2bc10fd6a14341f",
|
|
40
|
-
"session-store.js": "
|
|
41
|
-
"test/device-enrollment.test.js": "
|
|
40
|
+
"session-store.js": "ee85e5b9696e542bb535a996743ddbbd2093fc66e18873a2f1c7a27707a83994",
|
|
41
|
+
"test/device-enrollment.test.js": "a4246f4cb19e959ef4b8a83f60664887b624526b0e5646e5ec1fdb93750082b0",
|
|
42
42
|
"test/lightpanda-session.test.js": "1fa6c1693a5008c173ec6c5c97effe001b68c535c7a3d4530500c0c4b691c532",
|
|
43
43
|
"test/onboarding-state.test.js": "889f7746bbdb51320e68447560459d2a5d812e4b135de08a7b6e94ef5a142250",
|
|
44
44
|
"test/session-redaction.test.js": "e45b5cbd19eea7996d57141b5185c3a6e4c79989e4cb7253272fc66cd2cbd719",
|
|
45
|
-
"test/session-refresh.test.js": "
|
|
45
|
+
"test/session-refresh.test.js": "ffa688433185c08696761f189df244ed9ac212731b012a3eb9a91da05b43dd56",
|
|
46
46
|
"test/session-selection.test.js": "ee1a15d42b156403d46d789a3ecf0a9c8f0019a00ab908276297d031243a89f5",
|
|
47
47
|
"test/session-send-state.test.js": "c8ccbdf0863c5de85f784e7e32436591fe2db16a2ef4c554f671c6352736d5b6",
|
|
48
48
|
"test/site-permissions.test.js": "27c297475c38ee1cbe7c7df210c767c157e03ecd379cde99a1b502268bda56ab",
|
|
49
|
-
"tool.manifest.json": "
|
|
49
|
+
"tool.manifest.json": "820f6060f077b95c286168f175e5521bc67b043425cae69c5be40834d5016454",
|
|
50
50
|
"web-store/listing.md": "3e6d7aab1f60142984c3f8c18d92bf23646dc901644c6b71bdb979802bcf320c",
|
|
51
|
-
"web-store/privacy-policy.md": "
|
|
51
|
+
"web-store/privacy-policy.md": "eaaaa6066b36ef56896321d62b6ac4596d62104a0591d4edceb8c6040c47fd5c"
|
|
52
|
+
},
|
|
53
|
+
"toolDependencies": {
|
|
54
|
+
"lightpanda-browser": "^0.11.5"
|
|
52
55
|
}
|
|
53
56
|
},
|
|
54
57
|
"campaign-draft-runner": {
|
|
@@ -115,6 +118,7 @@
|
|
|
115
118
|
"creator-scout": {
|
|
116
119
|
"version": "1.4.0",
|
|
117
120
|
"files": {
|
|
121
|
+
"README.md": "6895b2c0cc3a230ddf3f59f1c4670b12070464f8e742bfdf40a04120a7fefaea",
|
|
118
122
|
"config.js": "bab728665650b986c0eaef8e1be1c259ec42b1f83df4217c9780f5468d3c7666",
|
|
119
123
|
"index.js": "a544e5dbac9cb92e996c2b07690a18481a20b8b10c13c397412581ec9ac6bb04",
|
|
120
124
|
"outcome-contract.js": "5685bd8fbe4fcb608ee43a0148201206283013c1a60855c974a928c1d312480a",
|
|
@@ -122,13 +126,16 @@
|
|
|
122
126
|
"package.json": "19c61d77ec90fce64d1a3baa1acc5b29af23f7c0574964504bc69b19e38aa34f",
|
|
123
127
|
"panda-results.js": "24a31263b4a03e2c2719d9c54be7b5c022b17fb7dcb249eed33b93882518145b",
|
|
124
128
|
"panda-session.js": "69878ff01bfbf26afe4db0e2e6489b211e3aca100ba5353befefaea009636bb5",
|
|
125
|
-
"README.md": "6895b2c0cc3a230ddf3f59f1c4670b12070464f8e742bfdf40a04120a7fefaea",
|
|
126
129
|
"reference-match.js": "5ceb71bfe57763258d89c60936bb7e5b3166b6aa7127f9d2f8da49f01298f46b",
|
|
127
130
|
"test/outcome-contract.test.js": "dda85d1f56880b30d7fad3e8a27aacbb0808d91fc0addac6e0c38f9f0c4849bf",
|
|
128
131
|
"test/panda-results.test.js": "b918d6341251822292fe3e375ab66694a0f71f3c7a24e91be263ee36e5f3e92c",
|
|
129
132
|
"test/panda-session.test.js": "6cfa4e0543fab77c502c1103c60d8cb7d16040770e7aa5c034a47e0292de8521",
|
|
130
133
|
"test/reference-match.test.js": "38572ee3756f4ff0b0c61942dda0a19c9d06697826051cf0924dd3c47fc99b67",
|
|
131
134
|
"tool.manifest.json": "5368082b6808dc9b5966a46afcc6042cc82aabef0cd55ed65b4e783a4cb2579e"
|
|
135
|
+
},
|
|
136
|
+
"toolDependencies": {
|
|
137
|
+
"lightpanda-browser": "^0.11.4",
|
|
138
|
+
"browser-session-bridge": "^0.1.3"
|
|
132
139
|
}
|
|
133
140
|
},
|
|
134
141
|
"file-document": {
|
|
@@ -177,27 +184,27 @@
|
|
|
177
184
|
"lightpanda-browser": {
|
|
178
185
|
"version": "0.11.5",
|
|
179
186
|
"files": {
|
|
187
|
+
"BENCHMARK.md": "9c732c65f6d8bceb4e73c1a03d298d5140d919f50269f982bd0ec6c1b21fa8b6",
|
|
188
|
+
"COMPATIBILITY-MIGRATION.md": "230e12e8ddac837b7772519693e530c43d2158b69c671036bf246fb3a9e35561",
|
|
189
|
+
"LIMITS.md": "6c0ec9624c76de8ddf09b82a4da1dba1b89a48a1f0e71a083ffbcf7a3d5401fb",
|
|
190
|
+
"README.md": "c79a9a24d2fe804a7ce3e160e8308b1ac0039461cbfd012347aaa61f841f5fed",
|
|
180
191
|
"action-policy.js": "66c6ad39f65378ccf8ed54177f5a3665e23ef82818c30fb05d28cd58cba9b2ab",
|
|
181
192
|
"authenticated-profile.js": "2bbb96c4d25a108c44256514c1c9b4e61e1f125e470ab35c5e02515216cd1b33",
|
|
182
193
|
"benchmark-latest.json": "c5524e6d42479578579fd7db0e50857ff0831ca219e611b821ad1e0a4fade303",
|
|
183
194
|
"benchmark-policy.js": "2c3763d7f327293c9d54ca24da9e65b94dc304af44908c1e196a4af45ed49a89",
|
|
184
|
-
"BENCHMARK.md": "9c732c65f6d8bceb4e73c1a03d298d5140d919f50269f982bd0ec6c1b21fa8b6",
|
|
185
195
|
"binary.js": "accd3f1f536ae7ceee4dbfcee2de9ac56fc1ae343656238d62003233417257f1",
|
|
186
196
|
"browser-operation.js": "51384d146d45fda8c672d3d6672fa223b715ad40c3c5b5878719e9df38151592",
|
|
187
197
|
"capture.js": "b68b198d494c762822c6da079a556dd3463e681557f2abef1387d9cd41abaf4c",
|
|
188
|
-
"COMPATIBILITY-MIGRATION.md": "230e12e8ddac837b7772519693e530c43d2158b69c671036bf246fb3a9e35561",
|
|
189
198
|
"config.js": "d08eb436df15540a53b02cf72e117c7fc8ead80195dbd53764a17598c9e565c5",
|
|
190
199
|
"daemon-service.js": "10e70ed64f1fe8c7660044f6ce24e78d01da75a50322bfc08f42248c14ad5226",
|
|
191
200
|
"index.js": "5fc54aec13fb27c6b55e20aed132853b79c44041f45ea4b0f4b47b00c205da16",
|
|
192
201
|
"limit-suite-latest.json": "3d30f958d2d6c1e9dfcaf53e40a401ae288bf264a97ba6c3b64a25a08031feb0",
|
|
193
202
|
"limit-suite-policy.js": "61440ee2e7f557ab2f3c74f8ef4ec2ec85fd2fb7fc53a4121e1f0d066670ea17",
|
|
194
|
-
"LIMITS.md": "6c0ec9624c76de8ddf09b82a4da1dba1b89a48a1f0e71a083ffbcf7a3d5401fb",
|
|
195
203
|
"mcp-session.js": "cd4a1e6d3c9d80c399fda8f313d69e38fa22a9b24789d7919832a56df7dc90c2",
|
|
196
204
|
"output-bounds.js": "08ab730d0d8722c5e0e761911a509653dd23d8eb4d8c2abf2d9c5e8432870bdd",
|
|
197
205
|
"package-lock.json": "815dfdb89ce94b543e520955480e322438abd2b71fad4c4ddd699838b8622b65",
|
|
198
206
|
"package.json": "934ae0f55d1baea305c28f12c0c9faccdd864244d899663c96f9083d96442841",
|
|
199
207
|
"process-metrics.js": "e39d2980abb581ca0b917d0d33a1d71922ce49b679a7e96cf16a6a66b81d879a",
|
|
200
|
-
"README.md": "c79a9a24d2fe804a7ce3e160e8308b1ac0039461cbfd012347aaa61f841f5fed",
|
|
201
208
|
"recipe-store.js": "358ac391ae86e0bfb82fc5b55bd08cfe3fd4fa56ac12a5ad4ad5abfa43c9a6c6",
|
|
202
209
|
"scripts/benchmark.js": "f1bb939984460d84118317f9b4f811e0df80f590b0a441cd62a56eb97bb69b37",
|
|
203
210
|
"scripts/install-lightpanda.js": "ba4a2f9e5ffae80b9375578731d68eff25997333cb9e3e443b155f7834948205",
|
|
@@ -255,6 +262,7 @@
|
|
|
255
262
|
"master-slave": {
|
|
256
263
|
"version": "0.1.9",
|
|
257
264
|
"files": {
|
|
265
|
+
"README.md": "a75f87df7906fe143d2ecaddfe9263561db17436df7ec2c4a8d985e1e3e8996e",
|
|
258
266
|
"batch-cancellation.js": "b9ca57dfcca4f1a672d5435536b7eb83547dba98ed3fd09f34376f1d995bb97f",
|
|
259
267
|
"batch-runner.js": "97756a03b36278cd0315cc16da0c34a7821c322149c51ba6666f1c5081dbecbc",
|
|
260
268
|
"chat-state-store.js": "50de39aa33432733bb688eb01968e314a32b169324a66d0f0089b2a19ed9c880",
|
|
@@ -271,7 +279,6 @@
|
|
|
271
279
|
"master-domain.js": "10b7dfb43eb9939eb5baec54f742076cc73a2add6589a0ff57c51bc79c236faf",
|
|
272
280
|
"network-session.js": "6ef332ef9694ff211f4aed1e8b6ff4df3614a1d4c63affe6fdd00409329ec431",
|
|
273
281
|
"package.json": "774af304ec05a24461318172882a28373e568b5240d8eee9a31a286997b9a403",
|
|
274
|
-
"README.md": "a75f87df7906fe143d2ecaddfe9263561db17436df7ec2c4a8d985e1e3e8996e",
|
|
275
282
|
"remote-runtime.js": "d38b7a28f36e8f1be1d4826a056a03d0ebc2b9b17be277e010be25048797a562",
|
|
276
283
|
"slave-operations.js": "5a8967e2006f3f30ee221614d25fbf7863ffd9c717fd7eeeb0ba981c8c8c367a",
|
|
277
284
|
"state-store.js": "c56849a3f1b9c990128276e17963034a7836abacedc44f2e500d5732ebf9e451",
|
|
@@ -66,7 +66,7 @@ async function runInternalPiLogin(provider, { rl = null } = {}) {
|
|
|
66
66
|
|
|
67
67
|
export async function collectCliBootstrapChoices({ telegramApiKey, rl, ask }) {
|
|
68
68
|
const telegramMaxChatIds = Number(await ask("Maximum authorized chat IDs", "1"));
|
|
69
|
-
const runtime = createPiRuntime();
|
|
69
|
+
const runtime = await createPiRuntime();
|
|
70
70
|
const providers = sortBootstrapProviders(listPiProviders(runtime));
|
|
71
71
|
console.log("\nAvailable Pi providers:");
|
|
72
72
|
providers.forEach((item, index) => console.log(`${index + 1}. ${formatProviderOption(item)}`));
|
|
@@ -89,7 +89,7 @@ export async function collectCliBootstrapChoices({ telegramApiKey, rl, ask }) {
|
|
|
89
89
|
while (true) {
|
|
90
90
|
piApiKey = (await rl.question(`Pi API key for ${selectedProvider.provider} (optional): `)).trim();
|
|
91
91
|
if (piApiKey) break;
|
|
92
|
-
if (hasProviderAuth(selectedProvider.provider, createPiRuntime())) break;
|
|
92
|
+
if (hasProviderAuth(selectedProvider.provider, await createPiRuntime())) break;
|
|
93
93
|
if (!providerSupportsOAuth) {
|
|
94
94
|
console.log(`No existing Pi auth found for ${selectedProvider.provider}. This provider requires an API key.`);
|
|
95
95
|
continue;
|
|
@@ -100,7 +100,7 @@ export async function collectCliBootstrapChoices({ telegramApiKey, rl, ask }) {
|
|
|
100
100
|
} catch (error) {
|
|
101
101
|
console.log(`Internal Pi login failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
102
102
|
}
|
|
103
|
-
if (hasProviderAuth(selectedProvider.provider, createPiRuntime())) {
|
|
103
|
+
if (hasProviderAuth(selectedProvider.provider, await createPiRuntime())) {
|
|
104
104
|
console.log(`Detected Pi auth for ${selectedProvider.provider}. Continuing bootstrap.`);
|
|
105
105
|
break;
|
|
106
106
|
}
|