π PR chain β step 4 of 6 in #577
| # |
Issue |
PR |
Status |
| 1 |
#714 β Rename openai β apps |
#720 |
in review |
| 2 |
#715 β Capability auto-detect + gating |
#721 |
in review |
| 3 |
#716 β fetch-actor-details split (pilot) |
#722 |
in review |
| 4 |
#717 (this issue) |
#723 |
in review |
| 5 |
#718 β call-actor split |
#724 |
in review |
| 6 |
#719 β get-actor-run split |
#734 |
in review |
Parent: #577. Depends on: #714, #715, #716.
Context and motivation
Child of #577. Mirrors the fetch-actor-details split (#716). Depends on #714, #715, and ideally #716 (pattern validated first).
After this PR:
search-actors = data-only in both modes (replaces the search-actors-internal role)
search-actors-widget = widget-only, additive in apps mode
search-actors-internal = removed
Scope
In scope
- Align
search-actors across modes to pure data (current default behavior)
- Create
src/tools/apps/search_actors_widget.ts:
- Delete
src/tools/apps/search_actors.ts (base is now mode-independent) and src/tools/apps/search_actors_internal.ts
- Add
STORE_SEARCH_WIDGET to HelperTools; remove STORE_SEARCH_INTERNAL
- Update
src/tools/categories.ts, src/utils/server-instructions/apps.ts
- Update references in
src/tools/apps/call_actor.ts: STORE_SEARCH_INTERNAL β STORE_SEARCH
Out of scope
- Other tools (children 5β6)
- Widget UI code
Design notes
Files to modify / delete / create
| File |
Change |
src/tools/apps/search_actors_widget.ts |
create |
src/tools/apps/search_actors.ts |
delete (base is mode-independent) |
src/tools/apps/search_actors_internal.ts |
delete |
src/tools/categories.ts |
Register widget; drop internal; base is mode-independent |
src/const.ts |
Add STORE_SEARCH_WIDGET; remove STORE_SEARCH_INTERNAL |
src/tools/structured_output_schemas.ts |
Rename actorSearchInternalOutputSchema β widget variant |
src/utils/server-instructions/apps.ts |
Update references |
src/tools/apps/call_actor.ts |
Use base STORE_SEARCH |
Internal repo impact
STORE_SEARCH_INTERNAL removal β verify no internal-repo reference.
Testing strategy
Unit
search-actors returns identical output in both modes
search-actors-widget rejects extra params, returns widget shape
- Update
tests/unit/tools.mode_contract.test.ts
Integration
- Add
search-actors-widget case to tests/integration/suite.ts
mcpc probe (scripted β always run, compare UI vs non-UI)
Verifies the additive -widget layering: base tool stays byte-identical across modes; widget tool appears only in apps mode with correct _meta.
# Setup (one-time)
npm install -g @apify/mcpc
npm run build
# Connect both modes
APIFY_TOKEN=dummy mcpc connect "node dist/stdio.js" @default
APIFY_TOKEN=dummy mcpc connect "node dist/stdio.js --ui=true" @apps
# Capture tool shapes in both modes
mcpc --json @default tools-list \
| jq '.tools[] | select(.name | test("^search-actors")) | {name, _meta, inputSchema, outputSchema}' \
> /tmp/sa.default.json
mcpc --json @apps tools-list \
| jq '.tools[] | select(.name | test("^search-actors")) | {name, _meta, inputSchema, outputSchema}' \
> /tmp/sa.apps.json
diff /tmp/sa.default.json /tmp/sa.apps.json
Acceptance criteria:
Manual
- MCPJam: widget renders; ChatGPT: end-to-end parity
Verification checklist
π PR chain β step 4 of 6 in #577
openaiβappsfetch-actor-detailssplit (pilot)call-actorsplitget-actor-runsplitParent: #577. Depends on: #714, #715, #716.
Context and motivation
Child of #577. Mirrors the
fetch-actor-detailssplit (#716). Depends on #714, #715, and ideally #716 (pattern validated first).After this PR:
search-actors= data-only in both modes (replaces thesearch-actors-internalrole)search-actors-widget= widget-only, additive inappsmodesearch-actors-internal= removedScope
In scope
search-actorsacross modes to pure data (currentdefaultbehavior)src/tools/apps/search_actors_widget.ts:keywords,limit,offset(reusesearchActorsBaseArgsSchemaper refactor: Fold search-actors-internal args into shared schemaΒ #700)_meta.ui.resourceUri,_meta.ui.visibility = ["model","app"],_meta.ui.cspsrc/tools/apps/search_actors.ts(base is now mode-independent) andsrc/tools/apps/search_actors_internal.tsSTORE_SEARCH_WIDGETtoHelperTools; removeSTORE_SEARCH_INTERNALsrc/tools/categories.ts,src/utils/server-instructions/apps.tssrc/tools/apps/call_actor.ts:STORE_SEARCH_INTERNALβSTORE_SEARCHOut of scope
Design notes
searchActorsBaseArgsSchema(refactor: Fold search-actors-internal args into shared schemaΒ #700) reused for the widget input.actorSearchInternalOutputSchemaβactorSearchWidgetOutputSchema.Files to modify / delete / create
src/tools/apps/search_actors_widget.tssrc/tools/apps/search_actors.tssrc/tools/apps/search_actors_internal.tssrc/tools/categories.tssrc/const.tsSTORE_SEARCH_WIDGET; removeSTORE_SEARCH_INTERNALsrc/tools/structured_output_schemas.tsactorSearchInternalOutputSchemaβ widget variantsrc/utils/server-instructions/apps.tssrc/tools/apps/call_actor.tsSTORE_SEARCHInternal repo impact
STORE_SEARCH_INTERNALremoval β verify no internal-repo reference.Testing strategy
Unit
search-actorsreturns identical output in both modessearch-actors-widgetrejects extra params, returns widget shapetests/unit/tools.mode_contract.test.tsIntegration
search-actors-widgetcase totests/integration/suite.tsmcpc probe (scripted β always run, compare UI vs non-UI)
Verifies the additive
-widgetlayering: base tool stays byte-identical across modes; widget tool appears only in apps mode with correct_meta.Acceptance criteria:
search-actors; no-widget, no-internalsearch-actorsANDsearch-actors-widgetsearch-actorsinputSchema+outputSchemabyte-identical between modessearch-actors_metahas noui.*keys in either modesearch-actors-widget._meta.ui.resourceUri==ui://widget/search-actors.htmlsearch-actors-widget._meta.ui.visibility==["model","app"]search-actors-widget._meta.ui.cspis a non-empty objectManual
Verification checklist
npm run type-checkpassesnpm run lintpassesnpm run test:unitpasses-internalreferences remain