@pi-unipi/background-tasks 2.6.1
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 +87 -0
- package/extensions/anthropic-attribution.ts +1 -0
- package/extensions/delegate-child.ts +1 -0
- package/extensions/fusion-child.ts +1 -0
- package/package.json +40 -0
- package/src/__tests__/anthropic-attribution.test.ts +195 -0
- package/src/__tests__/config.test.ts +137 -0
- package/src/__tests__/core.test.ts +493 -0
- package/src/__tests__/delegate-artifacts.test.ts +528 -0
- package/src/__tests__/delegate-budget.test.ts +456 -0
- package/src/__tests__/delegate-launch.test.ts +676 -0
- package/src/__tests__/delegate-result-package.test.ts +350 -0
- package/src/__tests__/delegate-seed.test.ts +392 -0
- package/src/__tests__/durable-fs.test.ts +559 -0
- package/src/__tests__/extension-api.test.ts +579 -0
- package/src/__tests__/fusion-artifacts.test.ts +1039 -0
- package/src/__tests__/fusion-budget.test.ts +1356 -0
- package/src/__tests__/fusion-claude-cache.test.ts +320 -0
- package/src/__tests__/fusion-config.test.ts +335 -0
- package/src/__tests__/fusion-context-prompts.test.ts +670 -0
- package/src/__tests__/fusion-evaluation.test.ts +315 -0
- package/src/__tests__/fusion-extraction-equivalence.test.ts +58 -0
- package/src/__tests__/fusion-golden-bytes.test.ts +35 -0
- package/src/__tests__/fusion-high-cardinality.test.ts +192 -0
- package/src/__tests__/fusion-model-selector.test.ts +205 -0
- package/src/__tests__/fusion-orchestrator.test.ts +1194 -0
- package/src/__tests__/fusion-rpc.test.ts +369 -0
- package/src/__tests__/fusion-sdk.test.ts +1226 -0
- package/src/__tests__/fusion-v5-core.test.ts +219 -0
- package/src/__tests__/fusion-validate-orchestrator.test.ts +240 -0
- package/src/__tests__/fusion-web-fetch.test.ts +485 -0
- package/src/__tests__/fusion-workflows.test.ts +59 -0
- package/src/__tests__/helpers/delegate-deterministic-seed.ts +109 -0
- package/src/__tests__/helpers/delegate-seed-subprocess.ts +10 -0
- package/src/__tests__/helpers/fusion-canonical-subprocess.ts +21 -0
- package/src/__tests__/helpers/fusion-canonical.ts +140 -0
- package/src/__tests__/helpers/fusion-fake-pi.ts +279 -0
- package/src/__tests__/helpers/fusion-golden-corpus.ts +500 -0
- package/src/__tests__/helpers/fusion-high-cardinality.ts +140 -0
- package/src/__tests__/helpers/normalize.ts +22 -0
- package/src/__tests__/helpers/pi-hook-contract-evidence.json +18 -0
- package/src/__tests__/pi-launch.test.ts +202 -0
- package/src/__tests__/registry.test.ts +1580 -0
- package/src/__tests__/scripted-provider/delegate-ambient-provider.test.ts +130 -0
- package/src/__tests__/scripted-provider/delegate-child-guard.test.ts +631 -0
- package/src/__tests__/scripted-provider/delegate-guard-provider.ts +403 -0
- package/src/__tests__/scripted-provider/follow-up.test.ts +448 -0
- package/src/__tests__/scripted-provider/fusion-output-recovery.test.ts +132 -0
- package/src/__tests__/scripted-provider/fusion-reason.test.ts +310 -0
- package/src/__tests__/scripted-provider/fusion-runtime-guard.test.ts +163 -0
- package/src/__tests__/scripted-provider/hook-contract-provider.ts +179 -0
- package/src/__tests__/scripted-provider/hook-probe-a.ts +3 -0
- package/src/__tests__/scripted-provider/hook-probe-b.ts +3 -0
- package/src/__tests__/scripted-provider/hook-probe-extension.ts +126 -0
- package/src/__tests__/scripted-provider/output-recovery-provider.ts +153 -0
- package/src/__tests__/scripted-provider/pi-hook-contract-evidence.json +18 -0
- package/src/__tests__/scripted-provider/pi-hook-contract.test.ts +477 -0
- package/src/__tests__/scripted-provider/runtime-guard-probe.ts +28 -0
- package/src/__tests__/scripted-provider/runtime-guard-provider.ts +49 -0
- package/src/__tests__/scripted-provider/scripted-provider-extension.ts +408 -0
- package/src/__tests__/task-manager.test.ts +479 -0
- package/src/__tests__/windows-taskkill.test.ts +161 -0
- package/src/anthropic-attribution-path.ts +21 -0
- package/src/anthropic-attribution.ts +1983 -0
- package/src/attested-pi-run.ts +612 -0
- package/src/child-process.ts +55 -0
- package/src/common.ts +8 -0
- package/src/config.ts +292 -0
- package/src/context-parent-snapshot.ts +142 -0
- package/src/context-token-budget.ts +903 -0
- package/src/context-visible-conversation-v2.ts +551 -0
- package/src/delegate/artifacts.ts +487 -0
- package/src/delegate/budget.ts +415 -0
- package/src/delegate/hook-contract-evidence.json +18 -0
- package/src/delegate/hook-contract.ts +154 -0
- package/src/delegate/launch.ts +497 -0
- package/src/delegate/result-package.ts +459 -0
- package/src/delegate/runner.ts +449 -0
- package/src/delegate/seed.ts +423 -0
- package/src/delegate/types.ts +323 -0
- package/src/delegate-child-extension.ts +978 -0
- package/src/delegate-extension.ts +806 -0
- package/src/durable-fs.ts +386 -0
- package/src/extension-api.ts +548 -0
- package/src/fixtures/delegate-context-incident.json +17 -0
- package/src/fixtures/fusion-golden-bytes.json +310 -0
- package/src/fixtures/fusion-validate-golden-bytes.json +282 -0
- package/src/fusion/artifacts.ts +967 -0
- package/src/fusion/budget.ts +1162 -0
- package/src/fusion/child-protocol.ts +305 -0
- package/src/fusion/claude-cache.ts +207 -0
- package/src/fusion/clean-context.ts +91 -0
- package/src/fusion/config.ts +449 -0
- package/src/fusion/context.ts +265 -0
- package/src/fusion/evaluation.ts +800 -0
- package/src/fusion/orchestrator.ts +1288 -0
- package/src/fusion/output-contract.ts +34 -0
- package/src/fusion/pi-child.ts +2373 -0
- package/src/fusion/prompts.ts +345 -0
- package/src/fusion/result-package.ts +959 -0
- package/src/fusion/source-policy.ts +257 -0
- package/src/fusion/types.ts +1139 -0
- package/src/fusion/web-fetch.ts +1060 -0
- package/src/fusion/workflows.ts +184 -0
- package/src/fusion-child-extension.ts +1052 -0
- package/src/fusion-extension.ts +1293 -0
- package/src/index.ts +295 -0
- package/src/pi-launch.ts +225 -0
- package/src/registry.ts +2424 -0
- package/src/settings-overlay.ts +208 -0
- package/src/task-manager.ts +774 -0
- package/src/tools.ts +530 -0
- package/src/turndown.d.ts +15 -0
- package/src/types.ts +963 -0
- package/src/ui/fusion-model-selector.ts +322 -0
- package/src/windows-taskkill.ts +250 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { afterEach, describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { spawn } from 'node:child_process';
|
|
4
|
+
import { existsSync } from 'node:fs';
|
|
5
|
+
import { mkdir, mkdtemp, readFile, rm, symlink } from 'node:fs/promises';
|
|
6
|
+
import { tmpdir } from 'node:os';
|
|
7
|
+
import { join, resolve } from 'node:path';
|
|
8
|
+
import { prepareDelegateLaunch } from '../../delegate/runner.js';
|
|
9
|
+
import { loadDelegateHookContractEvidence } from '../../delegate/launch.js';
|
|
10
|
+
import type { DelegateExtensionMode } from '../../delegate/types.js';
|
|
11
|
+
import { sessionWith, userMessage } from '../helpers/fusion-canonical.js';
|
|
12
|
+
import { isolatedTestEnv } from '../helpers/normalize.js';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Fresh-process regression for extension-registered delegate providers.
|
|
16
|
+
*
|
|
17
|
+
* The provider exists only as an auto-discovered global extension in a temp Pi
|
|
18
|
+
* agent directory. It is never passed through `--extension`, so isolated mode
|
|
19
|
+
* cannot resolve it while explicit ambient mode can. The ambient child still
|
|
20
|
+
* receives the package guard and every non-extension isolation flag from the
|
|
21
|
+
* production argv builder.
|
|
22
|
+
*/
|
|
23
|
+
const roots: string[] = [];
|
|
24
|
+
const providerExtension = resolve('tests/scripted-provider/delegate-guard-provider.ts');
|
|
25
|
+
const piExecutable = resolve('node_modules/.bin/pi');
|
|
26
|
+
|
|
27
|
+
async function runChild(
|
|
28
|
+
mode: DelegateExtensionMode,
|
|
29
|
+
): Promise<{ code: number | null; stderr: string; artifactDir: string; argv: readonly string[] }> {
|
|
30
|
+
const root = await mkdtemp(join(tmpdir(), `pi-bg-delegate-${mode}-`));
|
|
31
|
+
roots.push(root);
|
|
32
|
+
const cwd = join(root, 'project');
|
|
33
|
+
const agentDir = join(root, 'agent');
|
|
34
|
+
const extensionsDir = join(agentDir, 'extensions');
|
|
35
|
+
await mkdir(cwd, { recursive: true });
|
|
36
|
+
await mkdir(extensionsDir, { recursive: true });
|
|
37
|
+
// A symlink keeps package imports resolving from this repository while still
|
|
38
|
+
// exercising Pi's global ambient-extension discovery path.
|
|
39
|
+
await symlink(providerExtension, join(extensionsDir, 'custom-provider.ts'));
|
|
40
|
+
|
|
41
|
+
const evidenceRaw = await readFile(
|
|
42
|
+
resolve('src/core/delegate/hook-contract-evidence.json'),
|
|
43
|
+
'utf8',
|
|
44
|
+
);
|
|
45
|
+
const prepared = await prepareDelegateLaunch({
|
|
46
|
+
ctx: {
|
|
47
|
+
cwd,
|
|
48
|
+
sessionManager: sessionWith([userMessage('ambient provider regression')]),
|
|
49
|
+
getSystemPrompt: () => 'parent system prompt',
|
|
50
|
+
},
|
|
51
|
+
toolCallId: 'ambient-provider-call',
|
|
52
|
+
prompt: 'Return the deterministic delegate answer.',
|
|
53
|
+
capability: 'inspect',
|
|
54
|
+
extensionMode: mode,
|
|
55
|
+
route: {
|
|
56
|
+
provider: 'pi-bg-delegate',
|
|
57
|
+
model: 'delegate-model',
|
|
58
|
+
qualified_id: 'pi-bg-delegate/delegate-model',
|
|
59
|
+
context_window_tokens: 200_000,
|
|
60
|
+
thinking_level: 'medium',
|
|
61
|
+
origin: 'explicit',
|
|
62
|
+
},
|
|
63
|
+
limitOverrides: { maxTurns: 4, maxToolCalls: 8, timeoutSeconds: 30 },
|
|
64
|
+
hookEvidence: loadDelegateHookContractEvidence(evidenceRaw),
|
|
65
|
+
cwd,
|
|
66
|
+
sessionId: `ambient-provider-${mode}`,
|
|
67
|
+
autoDeliver: 'never',
|
|
68
|
+
env: {
|
|
69
|
+
...process.env,
|
|
70
|
+
...isolatedTestEnv,
|
|
71
|
+
PI_CODING_AGENT_DIR: agentDir,
|
|
72
|
+
UNIPI_BG_DELEGATE_API_KEY: 'delegate-api-key',
|
|
73
|
+
UNIPI_BG_DELEGATE_SCENARIO: 'plain-answer',
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const result = await new Promise<{ code: number | null; stderr: string }>((resolveResult, reject) => {
|
|
78
|
+
const child = spawn(piExecutable, [...prepared.argv], {
|
|
79
|
+
cwd,
|
|
80
|
+
env: prepared.env,
|
|
81
|
+
stdio: ['pipe', 'ignore', 'pipe'],
|
|
82
|
+
});
|
|
83
|
+
let stderr = '';
|
|
84
|
+
child.stderr.setEncoding('utf8');
|
|
85
|
+
child.stderr.on('data', (chunk: string) => {
|
|
86
|
+
stderr += chunk;
|
|
87
|
+
});
|
|
88
|
+
child.once('error', reject);
|
|
89
|
+
child.once('close', (code) => resolveResult({ code, stderr }));
|
|
90
|
+
child.stdin.end(prepared.stdinBytes);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
...result,
|
|
95
|
+
artifactDir: prepared.store.artifactDirAbs,
|
|
96
|
+
argv: prepared.argv,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
afterEach(async () => {
|
|
101
|
+
for (const root of roots.splice(0)) await rm(root, { recursive: true, force: true });
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
void describe('delegate ambient extension provider discovery', { concurrency: false }, () => {
|
|
105
|
+
void it(
|
|
106
|
+
'fails closed in isolated mode and resolves the same pinned provider in ambient mode',
|
|
107
|
+
{ timeout: 60_000 },
|
|
108
|
+
async () => {
|
|
109
|
+
const isolated = await runChild('isolated');
|
|
110
|
+
assert.notEqual(isolated.code, 0);
|
|
111
|
+
assert.match(isolated.stderr, /Unknown provider "pi-bg-delegate"/);
|
|
112
|
+
assert.ok(isolated.argv.includes('--no-extensions'));
|
|
113
|
+
assert.equal(existsSync(join(isolated.artifactDir, 'result.json')), false);
|
|
114
|
+
|
|
115
|
+
const ambient = await runChild('ambient');
|
|
116
|
+
assert.equal(ambient.code, 0, ambient.stderr);
|
|
117
|
+
assert.ok(!ambient.argv.includes('--no-extensions'));
|
|
118
|
+
assert.ok(ambient.argv.includes('--no-skills'));
|
|
119
|
+
assert.ok(ambient.argv.includes('--no-prompt-templates'));
|
|
120
|
+
assert.ok(ambient.argv.includes('--no-themes'));
|
|
121
|
+
assert.ok(ambient.argv.includes('--no-context-files'));
|
|
122
|
+
const explicitExtensions = ambient.argv.flatMap((entry, index) =>
|
|
123
|
+
entry === '--extension' ? [ambient.argv[index + 1] ?? ''] : [],
|
|
124
|
+
);
|
|
125
|
+
assert.equal(explicitExtensions.length, 1);
|
|
126
|
+
assert.match(explicitExtensions[0] ?? '', /extensions\/delegate-child\.(?:ts|js)$/);
|
|
127
|
+
assert.ok(existsSync(join(ambient.artifactDir, 'result.json')));
|
|
128
|
+
},
|
|
129
|
+
);
|
|
130
|
+
});
|