qaas-python 0.2.0__py3-none-any.whl → 0.2.2__py3-none-any.whl
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.
- qaas/cli.py +6 -8
- qaas/conductor.py +22 -0
- qaas/target.py +18 -0
- {qaas_python-0.2.0.dist-info → qaas_python-0.2.2.dist-info}/METADATA +1 -1
- {qaas_python-0.2.0.dist-info → qaas_python-0.2.2.dist-info}/RECORD +8 -8
- {qaas_python-0.2.0.dist-info → qaas_python-0.2.2.dist-info}/WHEEL +0 -0
- {qaas_python-0.2.0.dist-info → qaas_python-0.2.2.dist-info}/entry_points.txt +0 -0
- {qaas_python-0.2.0.dist-info → qaas_python-0.2.2.dist-info}/licenses/LICENSE +0 -0
qaas/cli.py
CHANGED
|
@@ -449,16 +449,14 @@ def doctor(
|
|
|
449
449
|
|
|
450
450
|
|
|
451
451
|
def _agent_usable(spec, caps: dict[str, bool]) -> bool:
|
|
452
|
-
"""
|
|
452
|
+
"""Delegates to `target.agent_usable`, which the conductor also uses.
|
|
453
453
|
|
|
454
|
-
|
|
455
|
-
|
|
454
|
+
Two copies of this rule meant `qaas doctor` could report an agent unusable
|
|
455
|
+
while a run dispatched it anyway.
|
|
456
456
|
"""
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
return caps["live_api"] or caps["static_analysis"]
|
|
461
|
-
return True
|
|
457
|
+
from qaas.target import agent_usable
|
|
458
|
+
|
|
459
|
+
return agent_usable(spec.name, caps)
|
|
462
460
|
|
|
463
461
|
|
|
464
462
|
@app.command()
|
qaas/conductor.py
CHANGED
|
@@ -25,6 +25,7 @@ from typing import Any, Callable
|
|
|
25
25
|
|
|
26
26
|
from qaas.config import AgentSpec, SystemConfig, load_config
|
|
27
27
|
from qaas.envelope import DefectEnvelope
|
|
28
|
+
from qaas.target import agent_usable
|
|
28
29
|
from qaas.mcp.context import ToolContext
|
|
29
30
|
from qaas.runner import RunOutcome, run_agent
|
|
30
31
|
from qaas.store import RunStore, SystemMapStore
|
|
@@ -269,6 +270,27 @@ class Conductor:
|
|
|
269
270
|
async def _phase_discover(self, specs, store, budget, report, mode, map_version) -> None:
|
|
270
271
|
"""Discovery agents are independent. Run them concurrently, bounded."""
|
|
271
272
|
discovery = [s for name, s in specs.items() if s.layer == "discovery"]
|
|
273
|
+
|
|
274
|
+
# Skip agents this target cannot support. `qaas doctor` has always
|
|
275
|
+
# reported these ("agents that cannot: SURFACE"), but nothing acted on
|
|
276
|
+
# it, so a run against a target with no reachable UI would still
|
|
277
|
+
# dispatch SURFACE and spend its entire budget hunting a browser that
|
|
278
|
+
# was never there. Being told an agent cannot work and then watching it
|
|
279
|
+
# run is worse than not being told.
|
|
280
|
+
profile = getattr(self.config, "profile", None)
|
|
281
|
+
if profile is not None:
|
|
282
|
+
caps = profile.capabilities()
|
|
283
|
+
unusable = [s for s in discovery if not agent_usable(s.name, caps)]
|
|
284
|
+
if unusable:
|
|
285
|
+
discovery = [s for s in discovery if s not in unusable]
|
|
286
|
+
store.log(
|
|
287
|
+
"skipped",
|
|
288
|
+
reason="target cannot support these agents",
|
|
289
|
+
agents=[s.name for s in unusable],
|
|
290
|
+
)
|
|
291
|
+
for spec in unusable:
|
|
292
|
+
self._emit("skipped", agent=spec.name, reason="target lacks the capability")
|
|
293
|
+
|
|
272
294
|
if not discovery:
|
|
273
295
|
return
|
|
274
296
|
|
qaas/target.py
CHANGED
|
@@ -259,3 +259,21 @@ def load_target(name: str, targets_dir: Path | str = "config/targets") -> Target
|
|
|
259
259
|
# directory is the bug that hid `<project>/config/targets/` the moment anything
|
|
260
260
|
# wrote into `.qaas/config/targets/`; profiles layer across every config
|
|
261
261
|
# directory, and `config.target_files(dirs)` is the one place that knows it.
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def agent_usable(agent_name: str, caps: dict[str, bool]) -> bool:
|
|
265
|
+
"""Whether an agent can do useful work with the capabilities available.
|
|
266
|
+
|
|
267
|
+
Lives here, beside `capabilities()`, because it has two callers that must
|
|
268
|
+
agree: `qaas doctor` reports it, and the conductor acts on it. They did not
|
|
269
|
+
agree for a while -- doctor would say "agents that cannot: SURFACE" and then
|
|
270
|
+
a run would dispatch SURFACE anyway and spend its whole budget looking for a
|
|
271
|
+
browser that was never there. Being told an agent cannot work and then
|
|
272
|
+
watching it run is worse than not being told.
|
|
273
|
+
|
|
274
|
+
Everything except SURFACE can contribute from static analysis alone, at
|
|
275
|
+
lower confidence. SURFACE without a reachable UI has nothing to do at all.
|
|
276
|
+
"""
|
|
277
|
+
if agent_name == "SURFACE":
|
|
278
|
+
return caps.get("live_ui", False)
|
|
279
|
+
return True
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: qaas-python
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: A multi-agent QA system: finds real defects, reproduces them, files tickets, fixes them, and proves the fix
|
|
5
5
|
Project-URL: Homepage, https://github.com/allaabdella2-us/qa-multi-agent-system
|
|
6
6
|
Project-URL: Repository, https://github.com/allaabdella2-us/qa-multi-agent-system
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
qaas/cli.py,sha256=
|
|
2
|
-
qaas/conductor.py,sha256=
|
|
1
|
+
qaas/cli.py,sha256=X8CZfVzVWxRpk3No1i-Ev0vD_Sle8Zba-b_uY9jv8c8,65366
|
|
2
|
+
qaas/conductor.py,sha256=woPR7tGiGWTWIqikn69ucMP_C5Bjo4NGwBK6RUpE9fI,24181
|
|
3
3
|
qaas/config.py,sha256=ZzgK0KUy7MR31w0o7fe1D2tYl--jkZCN_VaWR2kK1Xs,17528
|
|
4
4
|
qaas/discover.py,sha256=L5ejBsYs_s41OWAL-Dhc8VlQ5EWw2hGayWTDzfj05R8,8524
|
|
5
5
|
qaas/envelope.py,sha256=IiqyOy96CHZw2A0pSDWBNIg6yQ2MzfcwkpQWmgMNvzY,9095
|
|
@@ -10,7 +10,7 @@ qaas/runner.py,sha256=ED0arzgx0_Y6R_mcG6OXqzh3GeSOpqVUNa4NJ0QcRk8,7417
|
|
|
10
10
|
qaas/scorecard.py,sha256=aUU7g5OtXIW4752A4NxpIZH-OdC8bpNtzJUvCi41JYg,15809
|
|
11
11
|
qaas/sdk_compat.py,sha256=ftE6PK0jZY85zkYqS7UJTGYwRkYDlH4NspiKbKVfVXQ,1678
|
|
12
12
|
qaas/store.py,sha256=aDJmeCog17zo_Dw2Pw_JHTcWnDQlDW3QKzNnUttVvg8,11038
|
|
13
|
-
qaas/target.py,sha256
|
|
13
|
+
qaas/target.py,sha256=j0G7EGlI6FtdzM5vTvLOjhTIsX2qDU8kFiNrSrq83Gs,11222
|
|
14
14
|
qaas/tasks.py,sha256=vQh3leld5OE6zK3gfxZxbCM5ZixOQOzheJ_8ZomgHgE,17146
|
|
15
15
|
qaas/trace.py,sha256=V-uFqh1iCYRqgWL3VzDbRdHgAkwLsr1uRFfwwycWZ94,11461
|
|
16
16
|
qaas/adapters/__init__.py,sha256=bw2pqtDqhZGP730gwV28BJ-8TF-rhanwCEjdIizjP6A,882
|
|
@@ -78,8 +78,8 @@ qaas/prompts/SURFACE.md,sha256=cZ9df27bXXRh39yEkwByyxvHskpcNmh6HvC9C3Jt83Y,2220
|
|
|
78
78
|
qaas/prompts/VAULT.md,sha256=Ansowimx-wMbinQkn9_gGgZFmvmMFMc9v_N8s2Ahws4,2915
|
|
79
79
|
qaas/prompts/WARDEN.md,sha256=39KsbwWRwe7mtjYEik1owBIDgu4qyD52UHG_T_7gTMw,2950
|
|
80
80
|
qaas/prompts/_shared.md,sha256=lN_s_rAmakhGuyRuWItC--iyy-Er6ohT_dzGeE_g-fo,2620
|
|
81
|
-
qaas_python-0.2.
|
|
82
|
-
qaas_python-0.2.
|
|
83
|
-
qaas_python-0.2.
|
|
84
|
-
qaas_python-0.2.
|
|
85
|
-
qaas_python-0.2.
|
|
81
|
+
qaas_python-0.2.2.dist-info/METADATA,sha256=14s_84tja39SMIyEwaYPKZ_fLHtFJr9rgSpPmAykY5s,15528
|
|
82
|
+
qaas_python-0.2.2.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
83
|
+
qaas_python-0.2.2.dist-info/entry_points.txt,sha256=6UScfruyhP9N_xGx3tXJGkaoAiB36dkINuKyOH6OkK4,38
|
|
84
|
+
qaas_python-0.2.2.dist-info/licenses/LICENSE,sha256=pHWke5oMtv7PLjIQbN6hRa31J0AKj51VCd5TCTUbbX0,1069
|
|
85
|
+
qaas_python-0.2.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|