@pikku/core 0.12.139 → 0.12.142
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/CHANGELOG.md +47 -0
- package/dist/errors/errors.d.ts +1 -1
- package/dist/errors/errors.js +1 -1
- package/dist/function/function-meta.types.d.ts +6 -6
- package/dist/function/functions.types.d.ts +2 -2
- package/dist/lifecycle.d.ts +6 -0
- package/dist/lifecycle.js +58 -0
- package/dist/services/audit-service.d.ts +4 -4
- package/dist/services/feature-flag-service.d.ts +3 -3
- package/dist/services/{http-personas.d.ts → http-virtual-users.d.ts} +25 -47
- package/dist/services/{http-personas.js → http-virtual-users.js} +29 -53
- package/dist/services/index.d.ts +2 -2
- package/dist/services/index.js +1 -1
- package/dist/services/meta-service.d.ts +6 -6
- package/dist/services/meta-service.js +8 -8
- package/dist/{wirings/workflow → services}/scenario-cookie-jar.d.ts +2 -0
- package/dist/{wirings/workflow → services}/scenario-cookie-jar.js +18 -14
- package/dist/services/scoped-secret-service.d.ts +1 -0
- package/dist/services/scoped-secret-service.js +3 -0
- package/dist/services/secret-service.d.ts +6 -0
- package/dist/services/system-role-guard.d.ts +1 -1
- package/dist/services/typed-secret-service.d.ts +1 -0
- package/dist/services/typed-secret-service.js +7 -0
- package/dist/services/virtual-user-sign-in.d.ts +52 -0
- package/dist/services/virtual-user-sign-in.js +80 -0
- package/dist/services/virtual-user-statement.d.ts +31 -0
- package/dist/services/virtual-user-statement.js +24 -0
- package/dist/services/{personas-service.d.ts → virtual-users-service.d.ts} +25 -23
- package/dist/services/{personas-service.js → virtual-users-service.js} +3 -3
- package/dist/testing/service-tests/secret-service-tests.js +9 -0
- package/dist/types/core.types.d.ts +11 -11
- package/dist/utils.d.ts +2 -5
- package/dist/utils.js +1 -38
- package/dist/wirings/cli/cli-runner.js +24 -9
- package/dist/wirings/http/http-runner.js +4 -0
- package/dist/wirings/http/http.types.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
- package/dist/wirings/http/pikku-fetch-http-response.js +12 -0
- package/dist/wirings/http/web-request.js +7 -0
- package/dist/wirings/role/define-system-role.d.ts +1 -1
- package/dist/wirings/role/define-system-role.js +1 -1
- package/dist/wirings/{actor-flow/actor-flow.types.d.ts → virtual-user/conversation/conversation.types.d.ts} +5 -5
- package/dist/wirings/virtual-user/conversation/index.d.ts +2 -0
- package/dist/wirings/virtual-user/conversation/run-conversation.d.ts +36 -0
- package/dist/wirings/{actor-flow → virtual-user/conversation}/run-conversation.js +30 -30
- package/dist/wirings/virtual-user/define-virtual-users.d.ts +32 -0
- package/dist/wirings/{persona/define-personas.js → virtual-user/define-virtual-users.js} +9 -9
- package/dist/wirings/virtual-user/index.d.ts +30 -7
- package/dist/wirings/virtual-user/index.js +23 -4
- package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +8 -8
- package/dist/wirings/virtual-user/prepare-virtual-user-run.js +9 -9
- package/dist/wirings/virtual-user/run-virtual-user.d.ts +6 -6
- package/dist/wirings/virtual-user/run-virtual-user.js +10 -10
- package/dist/wirings/{persona/validate-personas.d.ts → virtual-user/validate-virtual-users.d.ts} +11 -11
- package/dist/wirings/{persona/validate-personas.js → virtual-user/validate-virtual-users.js} +24 -24
- package/dist/wirings/virtual-user/virtual-user-agents.d.ts +7 -7
- package/dist/wirings/virtual-user/virtual-user-agents.js +2 -2
- package/dist/wirings/{persona/persona-app-scopes.d.ts → virtual-user/virtual-user-app-scopes.d.ts} +10 -10
- package/dist/wirings/{persona/persona-app-scopes.js → virtual-user/virtual-user-app-scopes.js} +12 -12
- package/dist/wirings/virtual-user/virtual-user-catalogue.d.ts +3 -3
- package/dist/wirings/virtual-user/virtual-user-catalogue.js +2 -2
- package/dist/wirings/{persona/persona.types.d.ts → virtual-user/virtual-user-declaration.types.d.ts} +24 -24
- package/dist/wirings/virtual-user/virtual-user-derive.js +13 -7
- package/dist/wirings/virtual-user/virtual-user-dispositions.d.ts +1 -1
- package/dist/wirings/{persona/persona-email.d.ts → virtual-user/virtual-user-email.d.ts} +11 -11
- package/dist/wirings/{persona/persona-email.js → virtual-user/virtual-user-email.js} +19 -19
- package/dist/wirings/{persona/persona-environments.d.ts → virtual-user/virtual-user-environments.d.ts} +10 -10
- package/dist/wirings/{persona/persona-environments.js → virtual-user/virtual-user-environments.js} +21 -21
- package/dist/wirings/virtual-user/virtual-user-intents.d.ts +3 -3
- package/dist/wirings/virtual-user/virtual-user-intents.js +3 -3
- package/dist/wirings/{persona/persona-mailbox.d.ts → virtual-user/virtual-user-mailbox.d.ts} +4 -4
- package/dist/wirings/virtual-user/virtual-user-run-store.d.ts +4 -4
- package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +42 -61
- package/dist/wirings/virtual-user/virtual-user-scaffold.js +69 -117
- package/dist/wirings/virtual-user/virtual-user-schedule-store.d.ts +15 -15
- package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +6 -6
- package/dist/wirings/virtual-user/virtual-user-schedule.js +11 -11
- package/dist/wirings/virtual-user/virtual-user-target.d.ts +6 -6
- package/dist/wirings/virtual-user/virtual-user-target.js +5 -5
- package/dist/wirings/virtual-user/virtual-user.types.d.ts +11 -11
- package/dist/wirings/virtual-user/virtual-user.types.js +1 -1
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +9 -9
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +28 -28
- package/dist/wirings/workflow/pikku-scenario-service.js +77 -77
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -2
- package/dist/wirings/workflow/pikku-workflow-service.js +4 -4
- package/dist/wirings/workflow/scenario-prose.d.ts +8 -8
- package/dist/wirings/workflow/scenario-prose.js +12 -8
- package/dist/wirings/workflow/scenario-run.types.d.ts +13 -13
- package/dist/wirings/workflow/scenario-step.types.d.ts +23 -23
- package/dist/wirings/workflow/workflow.types.d.ts +2 -2
- package/knowledge/decisions/index.md +0 -2
- package/knowledge/decisions/internals/a-credential-name-declared-twice-must-agree-on-schema-and-type.md +29 -0
- package/knowledge/decisions/internals/a-grant-can-name-a-scope-declared-without-its-addon.md +29 -0
- package/knowledge/decisions/internals/a-scheduled-task-writes-its-caller-session-before-it-runs.md +22 -0
- package/knowledge/decisions/internals/a-secret-set-in-memory-shadows-the-variable-of-the-same-name.md +28 -0
- package/knowledge/decisions/internals/a-virtual-user-acts-through-invokeraw-so-a-refusal-is-data.md +32 -0
- package/knowledge/decisions/internals/a-virtual-user-cadence-is-a-row-not-a-timer.md +12 -12
- package/knowledge/decisions/internals/a-virtual-user-converse-signs-in-before-its-first-turn.md +24 -0
- package/knowledge/decisions/internals/a-virtual-user-email-is-computed-with-the-run-id-as-a-sub-address.md +34 -0
- package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-but-it-needs-a-trigger.md +2 -2
- package/knowledge/decisions/internals/an-agent-is-offered-under-its-registry-key-and-only-within-the-virtual-users-scopes.md +27 -0
- package/knowledge/decisions/internals/an-oauth2-credential-implies-an-optional-app-secret.md +26 -0
- package/knowledge/decisions/internals/analytics-identity-resolvers-run-in-declared-order.md +22 -0
- package/knowledge/decisions/internals/feature-flag-declarations-refuse-an-empty-anyof-and-conflicting-scopes.md +22 -0
- package/knowledge/decisions/internals/feature-flags-fail-open-and-never-enforce-access.md +28 -0
- package/knowledge/decisions/internals/flag-sync-rewrites-only-the-declared-text.md +24 -0
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +3 -3
- package/knowledge/decisions/internals/index.md +46 -31
- package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +10 -10
- package/knowledge/decisions/internals/role-names-cannot-contain-the-scope-separator.md +30 -0
- package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +23 -19
- package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +2 -2
- package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +12 -12
- package/knowledge/decisions/internals/the-core-scope-validator-refuses-separator-wildcard-and-empty-segments.md +22 -0
- package/knowledge/decisions/internals/the-pikku-user-id-resolves-in-a-fixed-order.md +24 -0
- package/knowledge/decisions/internals/{the-actor-prompt-says-json-because-of-json-object-mode.md → the-virtual-user-prompt-says-json-because-of-json-object-mode.md} +4 -4
- package/knowledge/decisions/internals/{the-persona-runtime-is-exported-from-the-persona-entry-point.md → the-virtual-user-runtime-is-exported-from-the-virtual-user-entry-point.md} +8 -8
- package/knowledge/decisions/internals/validate-checks-virtual-users-through-a-shared-module.md +43 -0
- package/knowledge/decisions/internals/{actor-flow-drives-the-target-through-a-transport-seam.md → virtual-user-conversation-drives-the-target-through-a-transport-seam.md} +6 -6
- package/knowledge/decisions/internals/virtual-user-conversation-verdicts-are-llm-self-evaluations.md +25 -0
- package/knowledge/decisions/internals/virtual-user-conversations-seed-a-hidden-kickoff-message.md +23 -0
- package/knowledge/decisions/internals/virtual-users-are-declared-in-one-definevirtualusers-call-per-codebase.md +30 -0
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +5 -5
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +2 -2
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +4 -4
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +1 -1
- package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +2 -2
- package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +1 -1
- package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +1 -1
- package/knowledge/decisions/security/a-bearer-token-checked-against-a-secret-reads-it-per-request.md +26 -0
- package/knowledge/decisions/security/a-call-without-a-session-raises-missing-session-not-forbidden.md +20 -0
- package/knowledge/decisions/security/a-caller-cookie-wins-over-the-jar-for-the-same-name.md +23 -0
- package/knowledge/decisions/security/a-channel-lifecycle-acts-as-the-socket-upgrade-session.md +16 -0
- package/knowledge/decisions/security/a-channel-requires-a-session-unless-it-says-auth-false.md +26 -0
- package/knowledge/decisions/security/a-credential-read-path-follows-its-declared-type-not-absence.md +32 -0
- package/knowledge/decisions/security/a-credential-type-is-a-literal-the-inspector-checks-at-declaration.md +27 -0
- package/knowledge/decisions/security/a-first-party-cookie-is-written-only-after-its-purposes-consent.md +33 -0
- package/knowledge/decisions/security/a-readonly-session-reaches-only-readonly-functions.md +25 -0
- package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +10 -5
- package/knowledge/decisions/security/a-scheduled-virtual-user-run-needs-no-admin-at-run-time.md +27 -0
- package/knowledge/decisions/security/a-scoped-credential-view-is-limited-to-declared-names.md +26 -0
- package/knowledge/decisions/security/a-scoped-secret-view-reads-only-declared-keys-and-never-writes.md +25 -0
- package/knowledge/decisions/security/a-secret-is-sent-only-to-the-hosts-it-declares.md +29 -0
- package/knowledge/decisions/security/a-step-can-name-an-identity-no-virtual-user-holds-through-per-call-headers.md +25 -0
- package/knowledge/decisions/security/a-stopped-run-by-id-skips-the-ownership-check.md +24 -0
- package/knowledge/decisions/security/a-vault-secret-redacts-on-serialization-and-throws-on-coercion.md +29 -0
- package/knowledge/decisions/security/a-virtual-user-catalogue-entry-is-filtered-by-scope-and-approval-is-denied-by-default.md +30 -0
- package/knowledge/decisions/security/a-virtual-user-environment-fails-closed.md +38 -0
- package/knowledge/decisions/security/a-virtual-user-never-runs-against-production.md +23 -0
- package/knowledge/decisions/security/a-virtual-user-reads-its-roles-from-the-apps-own-rpc-before-better-auth.md +27 -0
- package/knowledge/decisions/security/a-virtual-user-run-treats-an-unresolved-environment-as-production.md +41 -0
- package/knowledge/decisions/security/a-virtual-user-scopes-are-expanded-from-its-roles-once-at-run-preparation.md +25 -0
- package/knowledge/decisions/security/a-virtual-user-whose-roles-drift-from-the-declaration-refuses-to-run.md +32 -0
- package/knowledge/decisions/security/addon-screen-scopes-hide-and-do-not-enforce.md +20 -0
- package/knowledge/decisions/security/an-addon-header-can-only-narrow-the-session.md +26 -0
- package/knowledge/decisions/security/an-addon-instance-reads-only-the-secrets-and-credentials-it-is-named.md +33 -0
- package/knowledge/decisions/security/an-addon-may-reach-only-itself-and-the-addons-it-uses.md +16 -0
- package/knowledge/decisions/security/an-api-key-is-jwt-decoded-into-the-session.md +26 -0
- package/knowledge/decisions/security/an-external-virtual-user-caller-presents-one-signed-statement.md +38 -0
- package/knowledge/decisions/security/an-inbound-webhook-source-dispatches-only-verified-requests.md +31 -0
- package/knowledge/decisions/security/an-mcp-call-with-no-http-request-stays-anonymous.md +18 -0
- package/knowledge/decisions/security/an-omitted-user-id-addresses-the-platform-credential.md +32 -0
- package/knowledge/decisions/security/analytics-identity-is-stamped-from-the-session-not-the-event.md +24 -0
- package/knowledge/decisions/security/app-access-is-a-scope-tree-synthesised-from-virtual-users.md +26 -0
- package/knowledge/decisions/security/approval-policy-decides-who-answers-a-tool-call.md +27 -0
- package/knowledge/decisions/security/auth-false-on-a-session-function-warns-and-still-requires-one.md +25 -0
- package/knowledge/decisions/security/bearer-token-hashes-are-unpeppered-sha256.md +18 -0
- package/knowledge/decisions/security/consent-is-read-from-a-cookie-and-a-recognised-denial-counts-as-refusal.md +29 -0
- package/knowledge/decisions/security/cors-defaults-to-any-origin-and-refuses-the-wildcard-with-credentials.md +22 -0
- package/knowledge/decisions/security/credential-backends-share-one-conformance-suite-for-per-user-isolation.md +29 -0
- package/knowledge/decisions/security/each-stage-has-one-virtual-user-key-pair.md +27 -0
- package/knowledge/decisions/security/hmac-verification-fails-closed-on-empty-inputs.md +25 -0
- package/knowledge/decisions/security/index.md +88 -24
- package/knowledge/decisions/security/local-content-refuses-private-buckets-under-the-public-segment.md +21 -0
- package/knowledge/decisions/security/mail-is-allowlisted-before-a-virtual-user-run-sees-it.md +38 -0
- package/knowledge/decisions/security/mcp-resources-tools-and-prompts-take-sessionless-functions.md +18 -0
- package/knowledge/decisions/security/origin-locked-routes-match-the-origin-exactly.md +22 -0
- package/knowledge/decisions/security/oss-auth-works-without-pikku-studio-cloud.md +26 -0
- package/knowledge/decisions/security/outbound-webhooks-use-an-allowlist-when-configured.md +24 -0
- package/knowledge/decisions/security/pikku-carries-virtual-user-scopes-as-data-and-the-app-grants-them.md +35 -0
- package/knowledge/decisions/security/scoped-content-access-is-a-root-folder-with-longest-prefix-grants.md +31 -0
- package/knowledge/decisions/security/services-without-secrets-get-a-throwing-secrets-accessor.md +22 -0
- package/knowledge/decisions/security/shared-guards-refuse-to-mutate-or-shadow-a-system-role.md +34 -0
- package/knowledge/decisions/security/signed-uploads-are-verified-by-the-same-check-as-signed-reads.md +26 -0
- package/knowledge/decisions/security/system-role-scopes-must-be-declared-with-define-scope.md +24 -0
- package/knowledge/decisions/security/system-roles-are-additive-and-immutable.md +16 -0
- package/knowledge/decisions/security/the-channel-rpc-does-not-send-the-callers-session.md +21 -0
- package/knowledge/decisions/security/the-remote-jobs-inbox-fails-closed-without-a-secret.md +24 -0
- package/knowledge/decisions/security/the-remote-rpc-gate-fails-closed-and-binds-the-token-to-its-function.md +34 -0
- package/knowledge/decisions/security/the-workflow-status-stream-rechecks-ownership-on-every-poll.md +16 -0
- package/knowledge/decisions/security/two-credentials-on-one-key-must-share-a-read-mode.md +29 -0
- package/knowledge/decisions/security/verified-bearer-claims-are-pass-through-data-that-core-never-fills.md +23 -0
- package/knowledge/decisions/security/virtual-user-catalogue-excludes-the-machinery-that-runs-virtual-users.md +25 -0
- package/knowledge/decisions/security/{actor-flow-missing-approval-decisions-default-to-denied.md → virtual-user-conversation-missing-approval-decisions-default-to-denied.md} +7 -7
- package/knowledge/decisions/security/virtual-user-run-records-are-gated-behind-a-read-scope.md +18 -0
- package/knowledge/decisions/security/virtual-user-sign-in-does-not-exist-in-production.md +25 -0
- package/knowledge/decisions/security/virtual-user-sign-in-has-one-door.md +42 -0
- package/knowledge/decisions/security/{actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md → virtual-user-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md} +10 -8
- package/knowledge/decisions/security/virtual-user-sign-in-only-works-for-virtual-user-flagged-users.md +29 -0
- package/knowledge/decisions/security/workflow-helper-functions-are-sessionless-by-declaration.md +18 -0
- package/knowledge/decisions/security/{workflow-scenario-sessions-are-isolated-per-actor-and-per-scenario.md → workflow-scenario-sessions-are-isolated-per-virtual-user-and-per-scenario.md} +6 -6
- package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +5 -5
- package/knowledge/decisions/security/{workflow-actor-steps-always-use-the-real-transport.md → workflow-virtual-user-steps-always-use-the-real-transport.md} +11 -11
- package/knowledge/decisions/security/writing-a-virtual-user-schedule-is-gated-by-its-own-scope.md +18 -0
- package/knowledge/index.md +0 -2
- package/knowledge/questions/a-bearer-jwt-with-no-identity-becomes-a-session.md +24 -0
- package/knowledge/questions/dev-quick-login-as-impersonation.md +25 -0
- package/knowledge/questions/does-a-delayed-rpc-run-as-the-session-it-was-scheduled-with.md +26 -0
- package/knowledge/questions/does-a-user-id-with-a-colon-read-another-users-credentials.md +27 -0
- package/knowledge/questions/does-a-wirecli-command-need-a-session-by-default.md +26 -0
- package/knowledge/questions/does-an-adversarial-in-scope-success-count-as-a-finding.md +26 -0
- package/knowledge/questions/does-approve-step-need-the-run-owners-session-or-the-gates-approvers.md +34 -0
- package/knowledge/questions/does-cors-origin-true-reflect-any-origin-with-credentials.md +20 -0
- package/knowledge/questions/does-skip-user-session-do-anything-on-a-channel.md +24 -0
- package/knowledge/questions/does-the-store-session-match-the-other-two.md +19 -0
- package/knowledge/questions/index.md +25 -2
- package/knowledge/questions/is-the-agent-score-worker-reachable-without-a-session.md +21 -0
- package/knowledge/questions/live-scheduled-tests-may-write.md +19 -0
- package/knowledge/questions/provision-virtual-users-has-no-caller-in-this-repo.md +23 -0
- package/knowledge/questions/remote-secret-refuses-requests-without-a-remote-token-on-every-path.md +32 -0
- package/knowledge/questions/should-a-middleware-set-session-persist-to-the-store.md +25 -0
- package/knowledge/questions/should-a-scoped-secret-view-throw-from-has-secret-for-a-disallowed-key.md +23 -0
- package/knowledge/questions/should-a-wrong-bearer-token-be-anonymous-or-refused.md +35 -0
- package/knowledge/questions/should-an-empty-webhook-signing-secret-send-unsigned.md +23 -0
- package/knowledge/questions/should-http-virtual-user-sessions-reset-between-scenarios-in-one-run.md +27 -0
- package/knowledge/questions/should-the-cookie-jar-scope-cookies-to-the-api-origin.md +26 -0
- package/knowledge/questions/should-voice-input-fetch-audio-urls-without-a-host-allowlist.md +20 -0
- package/knowledge/questions/staging-impersonation-rules.md +27 -0
- package/knowledge/questions/virtual-user-keys-on-cloud-stages-are-pikku-studios-to-build.md +34 -0
- package/knowledge/questions/virtual-user-statement-replay-is-per-process.md +20 -0
- package/knowledge/questions/what-an-impersonated-session-carries.md +22 -0
- package/package.json +3 -3
- package/src/public-surface.json +43 -47
- package/dist/services/persona-actor-secret.d.ts +0 -38
- package/dist/services/persona-actor-secret.js +0 -39
- package/dist/services/persona-sign-in.d.ts +0 -117
- package/dist/services/persona-sign-in.js +0 -154
- package/dist/wirings/actor-flow/index.d.ts +0 -2
- package/dist/wirings/actor-flow/run-conversation.d.ts +0 -36
- package/dist/wirings/persona/define-personas.d.ts +0 -32
- package/dist/wirings/persona/index.d.ts +0 -23
- package/dist/wirings/persona/index.js +0 -19
- package/knowledge/decisions/internals/actor-flow-conversations-seed-a-hidden-kickoff-message.md +0 -23
- package/knowledge/decisions/internals/actor-flow-verdicts-are-llm-self-evaluations.md +0 -25
- package/knowledge/decisions/internals/validate-checks-personas-through-a-shared-module.md +0 -43
- package/knowledge/decisions/security/actor-sign-in-only-works-for-actor-flagged-users.md +0 -31
- package/knowledge/decisions/security/an-actor-credential-is-derived-per-persona.md +0 -42
- package/knowledge/decisions/security/pikku-carries-actor-scopes-as-data-and-the-app-grants-them.md +0 -26
- /package/dist/wirings/{actor-flow/actor-flow.types.js → virtual-user/conversation/conversation.types.js} +0 -0
- /package/dist/wirings/{actor-flow → virtual-user/conversation}/index.js +0 -0
- /package/dist/wirings/{persona/persona.types.js → virtual-user/virtual-user-declaration.types.js} +0 -0
- /package/dist/wirings/{persona/persona-mailbox.js → virtual-user/virtual-user-mailbox.js} +0 -0
|
@@ -164,6 +164,10 @@ const executeRoute = async (services, matchedRoute, http, options) => {
|
|
|
164
164
|
await originalClose();
|
|
165
165
|
};
|
|
166
166
|
}
|
|
167
|
+
response.onClose?.(() => {
|
|
168
|
+
channel.state = 'closed';
|
|
169
|
+
singletonServices.eventHub?.onChannelClosed(channelId);
|
|
170
|
+
});
|
|
167
171
|
}
|
|
168
172
|
const wire = {
|
|
169
173
|
traceId: requestId,
|
|
@@ -185,6 +185,7 @@ export interface PikkuHTTPResponse<Out = unknown> {
|
|
|
185
185
|
send?(data: string | ArrayBuffer | ArrayBufferView): this;
|
|
186
186
|
redirect(location: string, status?: number): this;
|
|
187
187
|
close?: () => void;
|
|
188
|
+
onClose?: (callback: () => void) => void;
|
|
188
189
|
setMode?: (mode: 'stream') => void;
|
|
189
190
|
flushHeaders?: () => void;
|
|
190
191
|
}
|
|
@@ -14,6 +14,7 @@ export declare class PikkuFetchHTTPResponse implements PikkuHTTPResponse {
|
|
|
14
14
|
send(data: any): this;
|
|
15
15
|
redirect(location: string, status?: number): this;
|
|
16
16
|
close(): this;
|
|
17
|
+
onClose(callback: () => void): void;
|
|
17
18
|
toResponse(args?: Record<string, any>): Response;
|
|
18
19
|
private createStream;
|
|
19
20
|
}
|
|
@@ -8,6 +8,7 @@ export class PikkuFetchHTTPResponse {
|
|
|
8
8
|
#send = null;
|
|
9
9
|
#close = null;
|
|
10
10
|
#cancelStream = null;
|
|
11
|
+
#onClose = [];
|
|
11
12
|
setMode(mode) {
|
|
12
13
|
this.#responseMode = 'stream';
|
|
13
14
|
if (mode === 'stream') {
|
|
@@ -95,6 +96,15 @@ export class PikkuFetchHTTPResponse {
|
|
|
95
96
|
}
|
|
96
97
|
return this;
|
|
97
98
|
}
|
|
99
|
+
onClose(callback) {
|
|
100
|
+
this.#onClose.push(callback);
|
|
101
|
+
}
|
|
102
|
+
#closed() {
|
|
103
|
+
const callbacks = this.#onClose;
|
|
104
|
+
this.#onClose = [];
|
|
105
|
+
for (const callback of callbacks)
|
|
106
|
+
callback();
|
|
107
|
+
}
|
|
98
108
|
toResponse(args) {
|
|
99
109
|
const cookieHeader = Array.from(this.#cookies.entries()).map(([name, { value, flags }]) => stringifySetCookie({ name, value, ...flags }, flags));
|
|
100
110
|
cookieHeader.forEach((cookie) => this.#headers.append('Set-Cookie', cookie));
|
|
@@ -119,9 +129,11 @@ export class PikkuFetchHTTPResponse {
|
|
|
119
129
|
return;
|
|
120
130
|
closed = true;
|
|
121
131
|
controller.close();
|
|
132
|
+
this.#closed();
|
|
122
133
|
};
|
|
123
134
|
this.#cancelStream = () => {
|
|
124
135
|
closed = true;
|
|
136
|
+
this.#closed();
|
|
125
137
|
};
|
|
126
138
|
this.#send = send;
|
|
127
139
|
this.#close = close;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js';
|
|
1
2
|
export function toWebRequest(req, baseUrl) {
|
|
2
3
|
const proto = req.header('x-forwarded-proto') ?? 'http';
|
|
3
4
|
const host = req.header('x-forwarded-host') ?? req.header('host') ?? 'localhost';
|
|
@@ -120,6 +121,12 @@ export async function applyWebResponse(res, webResponse) {
|
|
|
120
121
|
if (setCookieValues.length > 0) {
|
|
121
122
|
res.header('Set-Cookie', setCookieValues);
|
|
122
123
|
}
|
|
124
|
+
if (webResponse.body &&
|
|
125
|
+
res instanceof PikkuFetchHTTPResponse &&
|
|
126
|
+
webResponse.headers.get('content-type')?.startsWith('text/event-stream')) {
|
|
127
|
+
res.send(webResponse.body);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
123
130
|
const body = await readBody(webResponse);
|
|
124
131
|
if (body !== null) {
|
|
125
132
|
if (res.send) {
|
|
@@ -3,7 +3,7 @@ import type { CoreSystemRoles } from './role.types.js';
|
|
|
3
3
|
* No-op function for declaring system roles.
|
|
4
4
|
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
5
5
|
* The CLI extracts metadata via AST parsing and generates a `SystemRoleName`
|
|
6
|
-
* union, so a
|
|
6
|
+
* union, so a virtual user naming an undeclared role fails the build.
|
|
7
7
|
*
|
|
8
8
|
* A system role is a role that ships with the product: the console may grant
|
|
9
9
|
* it, but cannot rename, re-scope or delete it. Roles an admin composes in the
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* No-op function for declaring system roles.
|
|
3
3
|
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
4
4
|
* The CLI extracts metadata via AST parsing and generates a `SystemRoleName`
|
|
5
|
-
* union, so a
|
|
5
|
+
* union, so a virtual user naming an undeclared role fails the build.
|
|
6
6
|
*
|
|
7
7
|
* A system role is a role that ships with the product: the console may grant
|
|
8
8
|
* it, but cannot rename, re-scope or delete it. Roles an admin composes in the
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type ConversationApprovalPolicy = 'in-virtual-user' | 'always' | 'never';
|
|
2
2
|
export interface ConverseOptions<TAgentName extends string = string> {
|
|
3
3
|
agent: TAgentName;
|
|
4
|
-
/** What the
|
|
4
|
+
/** What the virtual user is trying to get the agent to accomplish. */
|
|
5
5
|
task: string;
|
|
6
|
-
/** Natural-language success criterion the
|
|
6
|
+
/** Natural-language success criterion the virtual user judges the conversation against. */
|
|
7
7
|
evaluate: string;
|
|
8
|
-
approvals?:
|
|
8
|
+
approvals?: ConversationApprovalPolicy;
|
|
9
9
|
model?: string;
|
|
10
10
|
maxTurns?: number;
|
|
11
11
|
}
|
|
12
|
-
export interface
|
|
12
|
+
export interface ConversationVerdict {
|
|
13
13
|
passed: boolean;
|
|
14
14
|
reasoning: string;
|
|
15
15
|
transcript: string[];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ConversationApprovalPolicy, ConversationVerdict, TargetAgentDriver } from './conversation.types.js';
|
|
2
|
+
import type { ResolvedVirtualUser } from '../../../services/virtual-users-service.js';
|
|
3
|
+
import type { AgentRunnerParams, AgentStepResult } from '../../../services/agent-runner-service.js';
|
|
4
|
+
/** The LLM call the virtual user uses for its own turns/decisions/evaluation. */
|
|
5
|
+
export type VirtualUserLLM = (params: AgentRunnerParams) => Promise<AgentStepResult>;
|
|
6
|
+
export interface RunConversationParams {
|
|
7
|
+
/** The person being played — name, job title, personality. */
|
|
8
|
+
virtualUser: ResolvedVirtualUser;
|
|
9
|
+
/** The id they were declared under (for transcript labelling). */
|
|
10
|
+
virtualUserId: string;
|
|
11
|
+
/** What the virtual user is trying to get the target agent to accomplish. */
|
|
12
|
+
task: string;
|
|
13
|
+
/** Natural-language success criterion the virtual user evaluates at the end. */
|
|
14
|
+
evaluate: string;
|
|
15
|
+
/** How the virtual user answers the target agent's tool-approval requests. */
|
|
16
|
+
approvals?: ConversationApprovalPolicy;
|
|
17
|
+
/** Model the virtual user uses for its own turns/decisions. */
|
|
18
|
+
model: string;
|
|
19
|
+
/** Hard cap on conversation turns. Default 12. */
|
|
20
|
+
maxTurns?: number;
|
|
21
|
+
/** Hard cap on tool-approval rounds within a single target turn. Default 16. */
|
|
22
|
+
maxApprovalRounds?: number;
|
|
23
|
+
/** Transport that drives the target agent (HTTP in production). */
|
|
24
|
+
target: TargetAgentDriver;
|
|
25
|
+
/** The virtual user's own LLM. */
|
|
26
|
+
llm: VirtualUserLLM;
|
|
27
|
+
/** Display name of the target agent (transcript labelling). */
|
|
28
|
+
agentName: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Run a conversation: an LLM-driven virtual user holds a real multi-turn exchange
|
|
32
|
+
* with a target agent (driven via the injected transport), answers the target's
|
|
33
|
+
* tool-approval requests in-virtual-user, then evaluates whether the task was met.
|
|
34
|
+
* Deterministic checks are the caller's responsibility.
|
|
35
|
+
*/
|
|
36
|
+
export declare function runConversation(params: RunConversationParams): Promise<ConversationVerdict>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/** One turn the
|
|
2
|
-
const
|
|
1
|
+
/** One turn the virtual user takes: the message to send and whether it's finished. */
|
|
2
|
+
const VIRTUAL_USER_TURN_SCHEMA = {
|
|
3
3
|
type: 'object',
|
|
4
4
|
properties: {
|
|
5
5
|
message: { type: 'string' },
|
|
@@ -7,7 +7,7 @@ const ACTOR_TURN_SCHEMA = {
|
|
|
7
7
|
},
|
|
8
8
|
required: ['message', 'done'],
|
|
9
9
|
};
|
|
10
|
-
/** The
|
|
10
|
+
/** The virtual user's approve/deny decision for each pending tool request. */
|
|
11
11
|
const APPROVAL_DECISION_SCHEMA = {
|
|
12
12
|
type: 'object',
|
|
13
13
|
properties: {
|
|
@@ -26,7 +26,7 @@ const APPROVAL_DECISION_SCHEMA = {
|
|
|
26
26
|
},
|
|
27
27
|
required: ['decisions'],
|
|
28
28
|
};
|
|
29
|
-
/** The
|
|
29
|
+
/** The virtual user's final verdict on whether the task was accomplished. */
|
|
30
30
|
const EVALUATION_SCHEMA = {
|
|
31
31
|
type: 'object',
|
|
32
32
|
properties: {
|
|
@@ -60,25 +60,25 @@ function readObject(result) {
|
|
|
60
60
|
}
|
|
61
61
|
return null;
|
|
62
62
|
}
|
|
63
|
-
function
|
|
63
|
+
function virtualUserConversationInstructions(virtualUser, task) {
|
|
64
64
|
return [
|
|
65
65
|
`You are role-playing a real user interacting with an AI assistant. Stay in character at all times — you are the user, not the assistant.`,
|
|
66
|
-
`Your name is ${
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
? `Your personality and communication style: ${
|
|
66
|
+
`Your name is ${virtualUser.name}.`,
|
|
67
|
+
virtualUser.jobTitle ? `Your role: ${virtualUser.jobTitle}.` : '',
|
|
68
|
+
virtualUser.personality
|
|
69
|
+
? `Your personality and communication style: ${virtualUser.personality}. Match this tone, vocabulary, and level of detail exactly.`
|
|
70
70
|
: '',
|
|
71
71
|
`Your goal in this conversation: ${task}.`,
|
|
72
72
|
`Send one message at a time. Set "done" to true only once your goal is clearly accomplished, or clearly impossible.`,
|
|
73
|
-
// knowledge: decisions/internals/the-
|
|
73
|
+
// knowledge: decisions/internals/the-virtual-user-prompt-says-json-because-of-json-object-mode.md
|
|
74
74
|
`Reply with json matching the schema you are given, and nothing else.`,
|
|
75
75
|
]
|
|
76
76
|
.filter(Boolean)
|
|
77
77
|
.join('\n');
|
|
78
78
|
}
|
|
79
|
-
/** Route the target agent's pending tool approvals through the
|
|
79
|
+
/** Route the target agent's pending tool approvals through the virtual user. */
|
|
80
80
|
async function decideApprovals(params, instructions, pending) {
|
|
81
|
-
const policy = params.approvals ?? 'in-
|
|
81
|
+
const policy = params.approvals ?? 'in-virtual-user';
|
|
82
82
|
if (policy === 'always') {
|
|
83
83
|
return pending.map((p) => ({ toolCallId: p.toolCallId, approved: true }));
|
|
84
84
|
}
|
|
@@ -90,7 +90,7 @@ async function decideApprovals(params, instructions, pending) {
|
|
|
90
90
|
.join('\n');
|
|
91
91
|
const result = await params.llm({
|
|
92
92
|
model: params.model,
|
|
93
|
-
instructions: `${instructions}\nThe assistant is asking permission to run tools on your behalf. Decide whether YOU, as this
|
|
93
|
+
instructions: `${instructions}\nThe assistant is asking permission to run tools on your behalf. Decide whether YOU, as this virtual user, would allow each one.`,
|
|
94
94
|
messages: [
|
|
95
95
|
msg('user', `The assistant wants to run these tools:\n${summary}\nApprove or deny each toolCallId.`),
|
|
96
96
|
],
|
|
@@ -106,7 +106,7 @@ async function decideApprovals(params, instructions, pending) {
|
|
|
106
106
|
return { toolCallId: p.toolCallId, approved: match?.approved ?? false };
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
|
-
/** Drive the target to a non-suspended reply, routing approvals to the
|
|
109
|
+
/** Drive the target to a non-suspended reply, routing approvals to the virtual user. */
|
|
110
110
|
async function converseWithTarget(params, instructions, message) {
|
|
111
111
|
const maxRounds = params.maxApprovalRounds ?? DEFAULT_MAX_APPROVAL_ROUNDS;
|
|
112
112
|
let reply = await params.target.run(message);
|
|
@@ -124,40 +124,40 @@ async function converseWithTarget(params, instructions, message) {
|
|
|
124
124
|
return reply;
|
|
125
125
|
}
|
|
126
126
|
/**
|
|
127
|
-
* Run a conversation: an LLM-driven
|
|
127
|
+
* Run a conversation: an LLM-driven virtual user holds a real multi-turn exchange
|
|
128
128
|
* with a target agent (driven via the injected transport), answers the target's
|
|
129
|
-
* tool-approval requests in-
|
|
129
|
+
* tool-approval requests in-virtual-user, then evaluates whether the task was met.
|
|
130
130
|
* Deterministic checks are the caller's responsibility.
|
|
131
131
|
*/
|
|
132
132
|
export async function runConversation(params) {
|
|
133
133
|
const maxTurns = params.maxTurns ?? DEFAULT_MAX_TURNS;
|
|
134
|
-
const instructions =
|
|
135
|
-
// Seed a kickoff so the very first
|
|
136
|
-
// (providers reject an empty prompt). It's an instruction TO the
|
|
134
|
+
const instructions = virtualUserConversationInstructions(params.virtualUser, params.task);
|
|
135
|
+
// Seed a kickoff so the very first virtual user turn has a non-empty message list
|
|
136
|
+
// (providers reject an empty prompt). It's an instruction TO the virtual user, so
|
|
137
137
|
// it never appears in the transcript.
|
|
138
|
-
const
|
|
138
|
+
const virtualUserMessages = [
|
|
139
139
|
msg('user', 'Begin the conversation now — send your first message to the assistant to work towards your goal.'),
|
|
140
140
|
];
|
|
141
141
|
const transcript = [];
|
|
142
142
|
for (let turn = 0; turn < maxTurns; turn++) {
|
|
143
|
-
const
|
|
143
|
+
const virtualUserResult = await params.llm({
|
|
144
144
|
model: params.model,
|
|
145
145
|
instructions,
|
|
146
|
-
messages:
|
|
146
|
+
messages: virtualUserMessages,
|
|
147
147
|
tools: [],
|
|
148
148
|
maxSteps: 1,
|
|
149
149
|
toolChoice: 'none',
|
|
150
|
-
outputSchema:
|
|
150
|
+
outputSchema: VIRTUAL_USER_TURN_SCHEMA,
|
|
151
151
|
});
|
|
152
|
-
const turnData = readObject(
|
|
153
|
-
const
|
|
154
|
-
if (!
|
|
152
|
+
const turnData = readObject(virtualUserResult);
|
|
153
|
+
const virtualUserMessage = turnData?.message?.trim();
|
|
154
|
+
if (!virtualUserMessage) {
|
|
155
155
|
break;
|
|
156
156
|
}
|
|
157
|
-
|
|
158
|
-
transcript.push(`${params.
|
|
159
|
-
const reply = await converseWithTarget(params, instructions,
|
|
160
|
-
|
|
157
|
+
virtualUserMessages.push(msg('assistant', virtualUserMessage));
|
|
158
|
+
transcript.push(`${params.virtualUser.name}: ${virtualUserMessage}`);
|
|
159
|
+
const reply = await converseWithTarget(params, instructions, virtualUserMessage);
|
|
160
|
+
virtualUserMessages.push(msg('user', reply.text ?? ''));
|
|
161
161
|
transcript.push(`${params.agentName}: ${reply.text ?? ''}`);
|
|
162
162
|
if (turnData?.done) {
|
|
163
163
|
break;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { CoreVirtualUsers } from './virtual-user-declaration.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* No-op function for declaring virtual users.
|
|
4
|
+
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
5
|
+
* The CLI extracts metadata via AST parsing and generates a `VirtualUserId` union
|
|
6
|
+
* and a `virtual-users.gen.json` the console and `pikku virtual-user run` read off disk —
|
|
7
|
+
* describing, listing or running one never has to load the app.
|
|
8
|
+
*
|
|
9
|
+
* Declaring is not running: a virtual user that exists only to be acted upon
|
|
10
|
+
* (the account an admin bans, the colleague a document is shared with) is
|
|
11
|
+
* seeded and never run.
|
|
12
|
+
*
|
|
13
|
+
* Exactly one `defineVirtualUsers(...)` is allowed per codebase, so there is one
|
|
14
|
+
* place to read the cast from and one place to add to. A second call — even in
|
|
15
|
+
* the same file — fails the build.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* defineVirtualUsers({
|
|
20
|
+
* susan: {
|
|
21
|
+
* name: 'Susan',
|
|
22
|
+
* jobTitle: 'Buys for a small café',
|
|
23
|
+
* roles: ['buyer'],
|
|
24
|
+
* personality: 'Hunts cheap deals. Tries three coupon codes before giving up.',
|
|
25
|
+
* goals: ['Get the weekly order in under five minutes'],
|
|
26
|
+
* disposition: 'careless',
|
|
27
|
+
* account: {},
|
|
28
|
+
* },
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare const defineVirtualUsers: (_config: CoreVirtualUsers) => void;
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* No-op function for declaring
|
|
2
|
+
* No-op function for declaring virtual users.
|
|
3
3
|
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
4
|
-
* The CLI extracts metadata via AST parsing and generates a `
|
|
5
|
-
* and a `
|
|
4
|
+
* The CLI extracts metadata via AST parsing and generates a `VirtualUserId` union
|
|
5
|
+
* and a `virtual-users.gen.json` the console and `pikku virtual-user run` read off disk —
|
|
6
6
|
* describing, listing or running one never has to load the app.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Declaring is not running: a virtual user that exists only to be acted upon
|
|
9
|
+
* (the account an admin bans, the colleague a document is shared with) is
|
|
10
|
+
* seeded and never run.
|
|
11
11
|
*
|
|
12
|
-
* Exactly one `
|
|
12
|
+
* Exactly one `defineVirtualUsers(...)` is allowed per codebase, so there is one
|
|
13
13
|
* place to read the cast from and one place to add to. A second call — even in
|
|
14
14
|
* the same file — fails the build.
|
|
15
15
|
*
|
|
16
16
|
* @example
|
|
17
17
|
* ```typescript
|
|
18
|
-
*
|
|
18
|
+
* defineVirtualUsers({
|
|
19
19
|
* susan: {
|
|
20
20
|
* name: 'Susan',
|
|
21
21
|
* jobTitle: 'Buys for a small café',
|
|
@@ -28,4 +28,4 @@
|
|
|
28
28
|
* })
|
|
29
29
|
* ```
|
|
30
30
|
*/
|
|
31
|
-
export const
|
|
31
|
+
export const defineVirtualUsers = (_config) => { };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Virtual user module exports.
|
|
3
3
|
*
|
|
4
|
-
* A virtual user is an LLM
|
|
4
|
+
* A virtual user is an LLM that signs into a *running* stage
|
|
5
5
|
* and works its API in character — non-deterministically, with a budget, and
|
|
6
6
|
* with oracles watching what comes back. It is not a test runner: nothing here
|
|
7
7
|
* asserts an expected outcome, because the point is the outcomes nobody thought
|
|
@@ -9,24 +9,47 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Everything it needs is derived from what a pikku project already generates —
|
|
11
11
|
* the function meta becomes the catalogue, the scenario meta becomes the
|
|
12
|
-
* intents, the declared
|
|
12
|
+
* intents, the declared virtual users become the identities — so adopting it is
|
|
13
13
|
* configuration rather than authoring.
|
|
14
14
|
*
|
|
15
15
|
* The engine is transport-agnostic: the virtual user drives an
|
|
16
|
-
* {@link VirtualUserTarget}, which in production is an `
|
|
16
|
+
* {@link VirtualUserTarget}, which in production is an `HttpVirtualUser`
|
|
17
17
|
* signed in as a real user against staging or production.
|
|
18
18
|
*/
|
|
19
19
|
export type { ApiCatalogueEntry, IntentRecord, IntentSource, StepRecord, VirtualUserBudget, VirtualUserDisposition, VirtualUserFinding, VirtualUserRunResult, VirtualUserTarget, } from './virtual-user.types.js';
|
|
20
20
|
export { PRODUCTION_DISPOSITION } from './virtual-user.types.js';
|
|
21
21
|
export { runVirtualUser, type RunVirtualUserParams, } from './run-virtual-user.js';
|
|
22
|
-
export {
|
|
22
|
+
export { virtualUserScopes, prepareVirtualUserRun, type VirtualUserPreparation, } from './prepare-virtual-user-run.js';
|
|
23
23
|
export type { VirtualUserRunOutcome, VirtualUserRunRecord, VirtualUserRunStart, VirtualUserRunStore, } from './virtual-user-run-store.js';
|
|
24
24
|
export type { VirtualUserScheduleInput, VirtualUserScheduleRecord, VirtualUserScheduleStore, } from './virtual-user-schedule-store.js';
|
|
25
25
|
export { DEFAULT_MAX_INTERVAL_MS, DEFAULT_MIN_INTERVAL_MS, isDue, nextRunAt, STALE_RUN_AFTER_MS, tickVirtualUserSchedules, type VirtualUserTickParams, type VirtualUserTickResult, } from './virtual-user-schedule.js';
|
|
26
26
|
export { DISPOSITIONS, dispositionProfile, type DispositionProfile, type VirtualUserTuning, } from './virtual-user-dispositions.js';
|
|
27
27
|
export { catalogueClassification, catalogueLookup, isReadOnly, reachableCatalogue, unreachableCatalogue, } from './virtual-user-catalogue.js';
|
|
28
28
|
export { type AgentReachability, type ReachableAgent, } from './virtual-user-agents.js';
|
|
29
|
-
export { IntentStack,
|
|
29
|
+
export { IntentStack, intentsForVirtualUser } from './virtual-user-intents.js';
|
|
30
30
|
export { deriveCatalogue, deriveIntents, type SchemaMap, } from './virtual-user-derive.js';
|
|
31
|
-
export {
|
|
32
|
-
export { executeVirtualUserRun, logVirtualUserTick, requireVirtualUserRunStore, requireVirtualUserScheduleStore,
|
|
31
|
+
export { virtualUserTarget, type VirtualUserTargetOptions, } from './virtual-user-target.js';
|
|
32
|
+
export { executeVirtualUserRun, logVirtualUserTick, requireVirtualUserRunStore, requireVirtualUserScheduleStore, runnableVirtualUser, serializeVirtualUserRun, serializeVirtualUserSchedule, serializeVirtualUserSteps, startVirtualUserRun, VIRTUAL_USER_VARIABLES, virtualUserScheduleRunInput, writeVirtualUserSchedule, type ExecuteVirtualUserRunParams, type ScaffoldVirtualUsers, type StartedVirtualUserRun, type StartVirtualUserRunParams, type WriteVirtualUserScheduleParams, } from './virtual-user-scaffold.js';
|
|
33
|
+
export { defineVirtualUsers } from './define-virtual-users.js';
|
|
34
|
+
export { isRunnableVirtualUser, roleMismatchMessage, runnableVirtualUsers, validateAndBuildVirtualUsersMeta, verifyVirtualUserRoles, } from './validate-virtual-users.js';
|
|
35
|
+
export type { RoleVerification } from './validate-virtual-users.js';
|
|
36
|
+
export { virtualUserEnvironmentErrors, virtualUserEnvironmentRefusal, } from './virtual-user-environments.js';
|
|
37
|
+
export type { VirtualUserEnvironment, VirtualUserEnvironmentSubject, } from './virtual-user-environments.js';
|
|
38
|
+
export { virtualUserEmail, virtualUserEmails } from './virtual-user-email.js';
|
|
39
|
+
export { APP_SCOPE_ROOT, appScopeId, buildAppScopeDefinition, } from './virtual-user-app-scopes.js';
|
|
40
|
+
export type { MailboxAllowlist, VirtualUserMailbox, ReceivedEmail, } from './virtual-user-mailbox.js';
|
|
41
|
+
export type { CoreVirtualUser, CoreVirtualUsers, VirtualUserAccountMeta, VirtualUserDefinitions, VirtualUserMeta, VirtualUsersMeta, } from './virtual-user-declaration.types.js';
|
|
42
|
+
/**
|
|
43
|
+
* Signing in as a virtual user and talking to a stage over HTTP.
|
|
44
|
+
*
|
|
45
|
+
* Deliberately reached through this entry point rather than `@pikku/core/services`.
|
|
46
|
+
* `HttpVirtualUser` pulls in the conversation runner and, through it, the
|
|
47
|
+
* agent runner — none of which a production server has any use for. Exporting it
|
|
48
|
+
* from the services barrel put that chain in the module graph of every app that
|
|
49
|
+
* imports services, which only a bundler could remove and an unbundled Node or
|
|
50
|
+
* Lambda deploy would load outright.
|
|
51
|
+
*/
|
|
52
|
+
export { HttpVirtualUser, createHttpVirtualUsers, type HttpVirtualUsersConfig, } from '../../services/http-virtual-users.js';
|
|
53
|
+
export { statementSignIn, inProcessSignIn, authMount, type VirtualUserSignIn, type VirtualUserStatementMint, type StatementSignInOptions, type InProcessAuth, } from '../../services/virtual-user-sign-in.js';
|
|
54
|
+
export { createCookieJar, type ScenarioCookieJar, } from '../../services/scenario-cookie-jar.js';
|
|
55
|
+
export { postScenarioJson, readScenarioHttpResponse, } from '../../services/virtual-users-service.js';
|
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
export { PRODUCTION_DISPOSITION } from './virtual-user.types.js';
|
|
2
2
|
export { runVirtualUser, } from './run-virtual-user.js';
|
|
3
|
-
export {
|
|
3
|
+
export { virtualUserScopes, prepareVirtualUserRun, } from './prepare-virtual-user-run.js';
|
|
4
4
|
export { DEFAULT_MAX_INTERVAL_MS, DEFAULT_MIN_INTERVAL_MS, isDue, nextRunAt, STALE_RUN_AFTER_MS, tickVirtualUserSchedules, } from './virtual-user-schedule.js';
|
|
5
5
|
export { DISPOSITIONS, dispositionProfile, } from './virtual-user-dispositions.js';
|
|
6
6
|
export { catalogueClassification, catalogueLookup, isReadOnly, reachableCatalogue, unreachableCatalogue, } from './virtual-user-catalogue.js';
|
|
7
|
-
export { IntentStack,
|
|
7
|
+
export { IntentStack, intentsForVirtualUser } from './virtual-user-intents.js';
|
|
8
8
|
export { deriveCatalogue, deriveIntents, } from './virtual-user-derive.js';
|
|
9
|
-
export {
|
|
10
|
-
export { executeVirtualUserRun, logVirtualUserTick, requireVirtualUserRunStore, requireVirtualUserScheduleStore,
|
|
9
|
+
export { virtualUserTarget, } from './virtual-user-target.js';
|
|
10
|
+
export { executeVirtualUserRun, logVirtualUserTick, requireVirtualUserRunStore, requireVirtualUserScheduleStore, runnableVirtualUser, serializeVirtualUserRun, serializeVirtualUserSchedule, serializeVirtualUserSteps, startVirtualUserRun, VIRTUAL_USER_VARIABLES, virtualUserScheduleRunInput, writeVirtualUserSchedule, } from './virtual-user-scaffold.js';
|
|
11
|
+
export { defineVirtualUsers } from './define-virtual-users.js';
|
|
12
|
+
export { isRunnableVirtualUser, roleMismatchMessage, runnableVirtualUsers, validateAndBuildVirtualUsersMeta, verifyVirtualUserRoles, } from './validate-virtual-users.js';
|
|
13
|
+
export { virtualUserEnvironmentErrors, virtualUserEnvironmentRefusal, } from './virtual-user-environments.js';
|
|
14
|
+
export { virtualUserEmail, virtualUserEmails } from './virtual-user-email.js';
|
|
15
|
+
export { APP_SCOPE_ROOT, appScopeId, buildAppScopeDefinition, } from './virtual-user-app-scopes.js';
|
|
16
|
+
/**
|
|
17
|
+
* Signing in as a virtual user and talking to a stage over HTTP.
|
|
18
|
+
*
|
|
19
|
+
* Deliberately reached through this entry point rather than `@pikku/core/services`.
|
|
20
|
+
* `HttpVirtualUser` pulls in the conversation runner and, through it, the
|
|
21
|
+
* agent runner — none of which a production server has any use for. Exporting it
|
|
22
|
+
* from the services barrel put that chain in the module graph of every app that
|
|
23
|
+
* imports services, which only a bundler could remove and an unbundled Node or
|
|
24
|
+
* Lambda deploy would load outright.
|
|
25
|
+
*/
|
|
26
|
+
export { HttpVirtualUser, createHttpVirtualUsers, } from '../../services/http-virtual-users.js';
|
|
27
|
+
export { statementSignIn, inProcessSignIn, authMount, } from '../../services/virtual-user-sign-in.js';
|
|
28
|
+
export { createCookieJar, } from '../../services/scenario-cookie-jar.js';
|
|
29
|
+
export { postScenarioJson, readScenarioHttpResponse, } from '../../services/virtual-users-service.js';
|
|
@@ -5,19 +5,19 @@ import { type SchemaMap } from './virtual-user-derive.js';
|
|
|
5
5
|
import { type AgentReachability, type ReachableAgent } from './virtual-user-agents.js';
|
|
6
6
|
import type { ApiCatalogueEntry, IntentSource } from './virtual-user.types.js';
|
|
7
7
|
/**
|
|
8
|
-
* The scopes a
|
|
8
|
+
* The scopes a virtual user holds, resolved through its roles.
|
|
9
9
|
*
|
|
10
|
-
* Roles are the only thing a
|
|
10
|
+
* Roles are the only thing a virtual user declares; scopes are what a function
|
|
11
11
|
* checks. Narrowing a virtual user's catalogue needs the second, so the
|
|
12
12
|
* expansion happens once, here, against the same `defineSystemRole` definitions
|
|
13
13
|
* the seed grants from.
|
|
14
14
|
*/
|
|
15
|
-
export declare const
|
|
15
|
+
export declare const virtualUserScopes: (virtualUser: {
|
|
16
16
|
roles?: readonly string[];
|
|
17
17
|
}, roleScopes: Record<string, readonly string[]>) => string[];
|
|
18
18
|
/** Everything a run needs that is derived rather than decided. */
|
|
19
19
|
export interface VirtualUserPreparation {
|
|
20
|
-
/** Every RPC the app exposes, narrowed to what this
|
|
20
|
+
/** Every RPC the app exposes, narrowed to what this virtual user can reach. */
|
|
21
21
|
catalogue: ApiCatalogueEntry[];
|
|
22
22
|
intents: IntentSource[];
|
|
23
23
|
scopes: string[];
|
|
@@ -27,18 +27,18 @@ export interface VirtualUserPreparation {
|
|
|
27
27
|
* Derive what a virtual user needs from what the project already generates.
|
|
28
28
|
*
|
|
29
29
|
* Shared because there are two callers with the same problem and different
|
|
30
|
-
* sources for it: `pikku
|
|
30
|
+
* sources for it: `pikku virtual-user run` reads the inspector state at build time,
|
|
31
31
|
* and the scaffolded `runVirtualUser` RPC reads `metaService` at runtime. They
|
|
32
|
-
* must agree — a
|
|
32
|
+
* must agree — a virtual user whose catalogue is narrower over RPC than on the CLI
|
|
33
33
|
* finds different things from the same seed, which is exactly the property a
|
|
34
34
|
* seed exists to give.
|
|
35
35
|
*
|
|
36
36
|
* Nothing here is authored for the virtual user's benefit: the function meta is
|
|
37
37
|
* the catalogue, the scenario meta is the intents, and the role definitions are
|
|
38
|
-
* what turn a
|
|
38
|
+
* what turn a virtual user's declared roles into the scopes a function checks.
|
|
39
39
|
*/
|
|
40
40
|
export declare const prepareVirtualUserRun: (input: {
|
|
41
|
-
|
|
41
|
+
virtualUser: {
|
|
42
42
|
roles?: readonly string[];
|
|
43
43
|
};
|
|
44
44
|
functionsMeta: FunctionsMeta;
|
|
@@ -2,16 +2,16 @@ import { flattenSystemRoleDefinitions } from '../role/validate-role-definitions.
|
|
|
2
2
|
import { deriveCatalogue, deriveIntents, } from './virtual-user-derive.js';
|
|
3
3
|
import { reachableAgents, } from './virtual-user-agents.js';
|
|
4
4
|
/**
|
|
5
|
-
* The scopes a
|
|
5
|
+
* The scopes a virtual user holds, resolved through its roles.
|
|
6
6
|
*
|
|
7
|
-
* Roles are the only thing a
|
|
7
|
+
* Roles are the only thing a virtual user declares; scopes are what a function
|
|
8
8
|
* checks. Narrowing a virtual user's catalogue needs the second, so the
|
|
9
9
|
* expansion happens once, here, against the same `defineSystemRole` definitions
|
|
10
10
|
* the seed grants from.
|
|
11
11
|
*/
|
|
12
|
-
export const
|
|
12
|
+
export const virtualUserScopes = (virtualUser, roleScopes) => {
|
|
13
13
|
const scopes = new Set();
|
|
14
|
-
for (const role of
|
|
14
|
+
for (const role of virtualUser.roles ?? []) {
|
|
15
15
|
for (const scope of roleScopes[role] ?? []) {
|
|
16
16
|
scopes.add(scope);
|
|
17
17
|
}
|
|
@@ -22,15 +22,15 @@ export const personaScopes = (persona, roleScopes) => {
|
|
|
22
22
|
* Derive what a virtual user needs from what the project already generates.
|
|
23
23
|
*
|
|
24
24
|
* Shared because there are two callers with the same problem and different
|
|
25
|
-
* sources for it: `pikku
|
|
25
|
+
* sources for it: `pikku virtual-user run` reads the inspector state at build time,
|
|
26
26
|
* and the scaffolded `runVirtualUser` RPC reads `metaService` at runtime. They
|
|
27
|
-
* must agree — a
|
|
27
|
+
* must agree — a virtual user whose catalogue is narrower over RPC than on the CLI
|
|
28
28
|
* finds different things from the same seed, which is exactly the property a
|
|
29
29
|
* seed exists to give.
|
|
30
30
|
*
|
|
31
31
|
* Nothing here is authored for the virtual user's benefit: the function meta is
|
|
32
32
|
* the catalogue, the scenario meta is the intents, and the role definitions are
|
|
33
|
-
* what turn a
|
|
33
|
+
* what turn a virtual user's declared roles into the scopes a function checks.
|
|
34
34
|
*/
|
|
35
35
|
export const prepareVirtualUserRun = (input) => {
|
|
36
36
|
const catalogue = deriveCatalogue(input.functionsMeta, input.schemas ?? {});
|
|
@@ -40,10 +40,10 @@ export const prepareVirtualUserRun = (input) => {
|
|
|
40
40
|
for (const role of flattenSystemRoleDefinitions(Array.isArray(declared) ? declared : Object.values(declared))) {
|
|
41
41
|
roleScopes[role.name] = role.scopes;
|
|
42
42
|
}
|
|
43
|
-
const scopes =
|
|
43
|
+
const scopes = virtualUserScopes(input.virtualUser, roleScopes);
|
|
44
44
|
// Gated by the same scopes as the RPCs, because an agent is reached rather
|
|
45
45
|
// than declared: `CoreAgent.scopes` is checked against the session, so a
|
|
46
|
-
//
|
|
46
|
+
// virtual user finds the specialists its roles unlock and no others.
|
|
47
47
|
const agents = reachableAgents(input.agentsMeta ?? {}, scopes);
|
|
48
48
|
return { catalogue, intents, scopes, agents };
|
|
49
49
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { ResolvedVirtualUser } from '../../services/virtual-users-service.js';
|
|
2
|
+
import type { VirtualUserLLM } from './conversation/run-conversation.js';
|
|
3
3
|
import { type VirtualUserTuning } from './virtual-user-dispositions.js';
|
|
4
4
|
import type { ApiCatalogueEntry, IntentSource, VirtualUserBudget, VirtualUserDisposition, VirtualUserFinding, VirtualUserRunResult, VirtualUserTally, VirtualUserTarget } from './virtual-user.types.js';
|
|
5
5
|
/** What an app-specific oracle is shown about one call. */
|
|
@@ -15,9 +15,9 @@ export interface VirtualUserCallContext {
|
|
|
15
15
|
}
|
|
16
16
|
export interface RunVirtualUserParams {
|
|
17
17
|
/** The person being run — name, job title, personality, goals. */
|
|
18
|
-
|
|
18
|
+
virtualUser: ResolvedVirtualUser;
|
|
19
19
|
/** The id they were declared under, as the intent sources refer to them. */
|
|
20
|
-
|
|
20
|
+
virtualUserId: string;
|
|
21
21
|
/** How it behaves. Default `realistic`. */
|
|
22
22
|
disposition?: VirtualUserDisposition;
|
|
23
23
|
/** Per-user overrides for that disposition's dials. */
|
|
@@ -31,7 +31,7 @@ export interface RunVirtualUserParams {
|
|
|
31
31
|
/** The transport it acts through. */
|
|
32
32
|
target: VirtualUserTarget;
|
|
33
33
|
/** The user's own LLM. */
|
|
34
|
-
llm:
|
|
34
|
+
llm: VirtualUserLLM;
|
|
35
35
|
model: string;
|
|
36
36
|
budget?: VirtualUserBudget;
|
|
37
37
|
/**
|
|
@@ -60,7 +60,7 @@ export interface RunVirtualUserParams {
|
|
|
60
60
|
/** Ids and slugs remembered from an earlier run, for a `stale` user. */
|
|
61
61
|
memory?: Record<string, string>;
|
|
62
62
|
/**
|
|
63
|
-
* The scopes this
|
|
63
|
+
* The scopes this virtual user actually holds, resolved from its roles at sign-in.
|
|
64
64
|
*
|
|
65
65
|
* Used two ways: to narrow a large catalogue to what it is entitled to reach,
|
|
66
66
|
* and as an oracle — a call whose scopes it does not hold that nonetheless
|