@stigmer/sdk 3.35.0 → 3.36.0
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/activity.d.ts.map +1 -1
- package/activity.js.map +1 -1
- package/artifact-routing.d.ts.map +1 -1
- package/artifact-routing.js.map +1 -1
- package/authorization-config.d.ts.map +1 -1
- package/authorization-config.js.map +1 -1
- package/billing.d.ts.map +1 -1
- package/billing.js.map +1 -1
- package/config.d.ts.map +1 -1
- package/config.js.map +1 -1
- package/cursor-accounts.d.ts.map +1 -1
- package/cursor-accounts.js.map +1 -1
- package/ensure-identity-account.d.ts.map +1 -1
- package/ensure-identity-account.js.map +1 -1
- package/errors.d.ts.map +1 -1
- package/errors.js.map +1 -1
- package/execution/approval-provenance.d.ts.map +1 -1
- package/execution/approval-provenance.js.map +1 -1
- package/execution/conversation-rules.d.ts.map +1 -1
- package/execution/conversation-rules.js.map +1 -1
- package/execution/execution-phases.d.ts.map +1 -1
- package/execution/execution-phases.js.map +1 -1
- package/execution/file-review-fold.d.ts.map +1 -1
- package/execution/file-review-fold.js.map +1 -1
- package/execution/to-display-file-change.d.ts.map +1 -1
- package/execution/to-display-file-change.js.map +1 -1
- package/execution/tool-view.d.ts.map +1 -1
- package/execution/tool-view.js.map +1 -1
- package/execution/transcript.d.ts.map +1 -1
- package/execution/transcript.js.map +1 -1
- package/gen/agent.d.ts.map +1 -1
- package/gen/agent.js.map +1 -1
- package/gen/agentchannel.d.ts.map +1 -1
- package/gen/agentchannel.js.map +1 -1
- package/gen/agentexecution.d.ts.map +1 -1
- package/gen/agentexecution.js.map +1 -1
- package/gen/agentinstance.d.ts.map +1 -1
- package/gen/agentinstance.js.map +1 -1
- package/gen/agentshare.d.ts.map +1 -1
- package/gen/agentshare.js.map +1 -1
- package/gen/apikey.d.ts.map +1 -1
- package/gen/apikey.js.map +1 -1
- package/gen/artifact.d.ts.map +1 -1
- package/gen/artifact.js.map +1 -1
- package/gen/authorization-config.d.ts.map +1 -1
- package/gen/authorization-config.js +2 -2
- package/gen/authorization-config.js.map +1 -1
- package/gen/bidi-stream.d.ts.map +1 -1
- package/gen/bidi-stream.js.map +1 -1
- package/gen/channelapp.d.ts.map +1 -1
- package/gen/channelapp.js.map +1 -1
- package/gen/client.d.ts.map +1 -1
- package/gen/client.js.map +1 -1
- package/gen/environment.d.ts.map +1 -1
- package/gen/environment.js.map +1 -1
- package/gen/errors.d.ts.map +1 -1
- package/gen/errors.js.map +1 -1
- package/gen/executioncontext.d.ts.map +1 -1
- package/gen/executioncontext.js.map +1 -1
- package/gen/iampolicy.d.ts.map +1 -1
- package/gen/iampolicy.js.map +1 -1
- package/gen/identityaccount.d.ts.map +1 -1
- package/gen/identityaccount.js.map +1 -1
- package/gen/identityprovider.d.ts.map +1 -1
- package/gen/identityprovider.js.map +1 -1
- package/gen/invitation.d.ts.map +1 -1
- package/gen/invitation.js.map +1 -1
- package/gen/license.d.ts.map +1 -1
- package/gen/license.js.map +1 -1
- package/gen/mcpserver.d.ts.map +1 -1
- package/gen/mcpserver.js.map +1 -1
- package/gen/memory.d.ts.map +1 -1
- package/gen/memory.js.map +1 -1
- package/gen/oauthapp.d.ts.map +1 -1
- package/gen/oauthapp.js.map +1 -1
- package/gen/organization.d.ts.map +1 -1
- package/gen/organization.js.map +1 -1
- package/gen/plan.d.ts.map +1 -1
- package/gen/plan.js.map +1 -1
- package/gen/platformclient.d.ts.map +1 -1
- package/gen/platformclient.js.map +1 -1
- package/gen/plugin.d.ts.map +1 -1
- package/gen/plugin.js.map +1 -1
- package/gen/proto-utils.d.ts.map +1 -1
- package/gen/proto-utils.js.map +1 -1
- package/gen/resource-availability.d.ts.map +1 -1
- package/gen/resource-availability.js.map +1 -1
- package/gen/schedule.d.ts.map +1 -1
- package/gen/schedule.js.map +1 -1
- package/gen/session.d.ts.map +1 -1
- package/gen/session.js.map +1 -1
- package/gen/skill.d.ts.map +1 -1
- package/gen/skill.js.map +1 -1
- package/gen/subscription.d.ts.map +1 -1
- package/gen/subscription.js.map +1 -1
- package/gen/team.d.ts.map +1 -1
- package/gen/team.js.map +1 -1
- package/gen/types.d.ts.map +1 -1
- package/gen/types.js.map +1 -1
- package/gen/workflow.d.ts.map +1 -1
- package/gen/workflow.js.map +1 -1
- package/gen/workflowexecution.d.ts.map +1 -1
- package/gen/workflowexecution.js.map +1 -1
- package/gen/workflowinstance.d.ts.map +1 -1
- package/gen/workflowinstance.js.map +1 -1
- package/github.d.ts.map +1 -1
- package/github.js.map +1 -1
- package/guest-auth.d.ts.map +1 -1
- package/guest-auth.js.map +1 -1
- package/iam-principal.d.ts.map +1 -1
- package/iam-principal.js.map +1 -1
- package/iam-role.d.ts.map +1 -1
- package/iam-role.js.map +1 -1
- package/index.d.ts.map +1 -1
- package/index.js.map +1 -1
- package/internal/interceptors.d.ts.map +1 -1
- package/internal/interceptors.js.map +1 -1
- package/manifest/client.d.ts.map +1 -1
- package/manifest/client.js.map +1 -1
- package/manifest/document.d.ts.map +1 -1
- package/manifest/document.js.map +1 -1
- package/manifest/index.d.ts.map +1 -1
- package/manifest/index.js.map +1 -1
- package/manifest/parse.d.ts.map +1 -1
- package/manifest/parse.js.map +1 -1
- package/manifest/redaction.d.ts.map +1 -1
- package/manifest/redaction.js.map +1 -1
- package/manifest/registry.d.ts.map +1 -1
- package/manifest/registry.js.map +1 -1
- package/manifest/serialize.d.ts.map +1 -1
- package/manifest/serialize.js.map +1 -1
- package/mcpserver-connect.d.ts.map +1 -1
- package/mcpserver-connect.js.map +1 -1
- package/node.d.ts.map +1 -1
- package/node.js.map +1 -1
- package/package.json +2 -2
- package/platform-client-auth.d.ts.map +1 -1
- package/platform-client-auth.js.map +1 -1
- package/platform.d.ts.map +1 -1
- package/platform.js.map +1 -1
- package/plugin.d.ts.map +1 -1
- package/plugin.js.map +1 -1
- package/provider-standing.d.ts.map +1 -1
- package/provider-standing.js.map +1 -1
- package/resource-availability.d.ts.map +1 -1
- package/resource-availability.js.map +1 -1
- package/runner-adapter.d.ts.map +1 -1
- package/runner-adapter.js.map +1 -1
- package/search.d.ts.map +1 -1
- package/search.js.map +1 -1
- package/session.d.ts.map +1 -1
- package/session.js.map +1 -1
- package/sharing.d.ts.map +1 -1
- package/sharing.js.map +1 -1
- package/skill.d.ts.map +1 -1
- package/skill.js.map +1 -1
- package/src/gen/authorization-config.ts +2 -2
- package/stigmer.d.ts.map +1 -1
- package/stigmer.js.map +1 -1
- package/transport.d.ts.map +1 -1
- package/transport.js.map +1 -1
- package/__tests__/billing.test.d.ts +0 -2
- package/__tests__/billing.test.d.ts.map +0 -1
- package/__tests__/billing.test.js +0 -120
- package/__tests__/billing.test.js.map +0 -1
- package/__tests__/config.test.d.ts +0 -2
- package/__tests__/config.test.d.ts.map +0 -1
- package/__tests__/config.test.js +0 -35
- package/__tests__/config.test.js.map +0 -1
- package/__tests__/ensure-identity-account.test.d.ts +0 -2
- package/__tests__/ensure-identity-account.test.d.ts.map +0 -1
- package/__tests__/ensure-identity-account.test.js +0 -108
- package/__tests__/ensure-identity-account.test.js.map +0 -1
- package/__tests__/errors.test.d.ts +0 -2
- package/__tests__/errors.test.d.ts.map +0 -1
- package/__tests__/errors.test.js +0 -228
- package/__tests__/errors.test.js.map +0 -1
- package/__tests__/gen/errors.test.d.ts +0 -2
- package/__tests__/gen/errors.test.d.ts.map +0 -1
- package/__tests__/gen/errors.test.js +0 -97
- package/__tests__/gen/errors.test.js.map +0 -1
- package/__tests__/gen/invitation-client.test.d.ts +0 -2
- package/__tests__/gen/invitation-client.test.d.ts.map +0 -1
- package/__tests__/gen/invitation-client.test.js +0 -106
- package/__tests__/gen/invitation-client.test.js.map +0 -1
- package/__tests__/gen/proto-utils.test.d.ts +0 -2
- package/__tests__/gen/proto-utils.test.d.ts.map +0 -1
- package/__tests__/gen/proto-utils.test.js +0 -85
- package/__tests__/gen/proto-utils.test.js.map +0 -1
- package/__tests__/gen/session-client.test.d.ts +0 -2
- package/__tests__/gen/session-client.test.d.ts.map +0 -1
- package/__tests__/gen/session-client.test.js +0 -152
- package/__tests__/gen/session-client.test.js.map +0 -1
- package/__tests__/guest-auth.test.d.ts +0 -2
- package/__tests__/guest-auth.test.d.ts.map +0 -1
- package/__tests__/guest-auth.test.js +0 -223
- package/__tests__/guest-auth.test.js.map +0 -1
- package/__tests__/iam-principal.test.d.ts +0 -2
- package/__tests__/iam-principal.test.d.ts.map +0 -1
- package/__tests__/iam-principal.test.js +0 -65
- package/__tests__/iam-principal.test.js.map +0 -1
- package/__tests__/manifest.test.d.ts +0 -2
- package/__tests__/manifest.test.d.ts.map +0 -1
- package/__tests__/manifest.test.js +0 -306
- package/__tests__/manifest.test.js.map +0 -1
- package/__tests__/mcpserver-connect.test.d.ts +0 -2
- package/__tests__/mcpserver-connect.test.d.ts.map +0 -1
- package/__tests__/mcpserver-connect.test.js +0 -146
- package/__tests__/mcpserver-connect.test.js.map +0 -1
- package/__tests__/node.test.d.ts +0 -2
- package/__tests__/node.test.d.ts.map +0 -1
- package/__tests__/node.test.js +0 -67
- package/__tests__/node.test.js.map +0 -1
- package/__tests__/platform-client-auth.test.d.ts +0 -2
- package/__tests__/platform-client-auth.test.d.ts.map +0 -1
- package/__tests__/platform-client-auth.test.js +0 -59
- package/__tests__/platform-client-auth.test.js.map +0 -1
- package/__tests__/platform.test.d.ts +0 -2
- package/__tests__/platform.test.d.ts.map +0 -1
- package/__tests__/platform.test.js +0 -52
- package/__tests__/platform.test.js.map +0 -1
- package/__tests__/plugin.test.d.ts +0 -2
- package/__tests__/plugin.test.d.ts.map +0 -1
- package/__tests__/plugin.test.js +0 -74
- package/__tests__/plugin.test.js.map +0 -1
- package/__tests__/resource-availability.test.d.ts +0 -2
- package/__tests__/resource-availability.test.d.ts.map +0 -1
- package/__tests__/resource-availability.test.js +0 -80
- package/__tests__/resource-availability.test.js.map +0 -1
- package/__tests__/runner-adapter.test.d.ts +0 -2
- package/__tests__/runner-adapter.test.d.ts.map +0 -1
- package/__tests__/runner-adapter.test.js +0 -88
- package/__tests__/runner-adapter.test.js.map +0 -1
- package/__tests__/session.test.d.ts +0 -6
- package/__tests__/session.test.d.ts.map +0 -1
- package/__tests__/session.test.js +0 -50
- package/__tests__/session.test.js.map +0 -1
- package/__tests__/sharing.test.d.ts +0 -2
- package/__tests__/sharing.test.d.ts.map +0 -1
- package/__tests__/sharing.test.js +0 -106
- package/__tests__/sharing.test.js.map +0 -1
- package/__tests__/skill.test.d.ts +0 -2
- package/__tests__/skill.test.d.ts.map +0 -1
- package/__tests__/skill.test.js +0 -117
- package/__tests__/skill.test.js.map +0 -1
- package/__tests__/stigmer.test.d.ts +0 -2
- package/__tests__/stigmer.test.d.ts.map +0 -1
- package/__tests__/stigmer.test.js +0 -127
- package/__tests__/stigmer.test.js.map +0 -1
- package/__tests__/update-input-roundtrip.test.d.ts +0 -2
- package/__tests__/update-input-roundtrip.test.d.ts.map +0 -1
- package/__tests__/update-input-roundtrip.test.js +0 -775
- package/__tests__/update-input-roundtrip.test.js.map +0 -1
- package/__tests__/update-input.test.d.ts +0 -2
- package/__tests__/update-input.test.d.ts.map +0 -1
- package/__tests__/update-input.test.js +0 -188
- package/__tests__/update-input.test.js.map +0 -1
- package/execution/__tests__/approval-provenance.test.d.ts +0 -2
- package/execution/__tests__/approval-provenance.test.d.ts.map +0 -1
- package/execution/__tests__/approval-provenance.test.js +0 -42
- package/execution/__tests__/approval-provenance.test.js.map +0 -1
- package/execution/__tests__/file-review-fold.corpus.test.d.ts +0 -2
- package/execution/__tests__/file-review-fold.corpus.test.d.ts.map +0 -1
- package/execution/__tests__/file-review-fold.corpus.test.js +0 -82
- package/execution/__tests__/file-review-fold.corpus.test.js.map +0 -1
- package/execution/__tests__/file-review-fold.test.d.ts +0 -2
- package/execution/__tests__/file-review-fold.test.d.ts.map +0 -1
- package/execution/__tests__/file-review-fold.test.js +0 -184
- package/execution/__tests__/file-review-fold.test.js.map +0 -1
- package/execution/__tests__/to-display-file-change.test.d.ts +0 -2
- package/execution/__tests__/to-display-file-change.test.d.ts.map +0 -1
- package/execution/__tests__/to-display-file-change.test.js +0 -81
- package/execution/__tests__/to-display-file-change.test.js.map +0 -1
- package/execution/__tests__/tool-view.file-changes.test.d.ts +0 -2
- package/execution/__tests__/tool-view.file-changes.test.d.ts.map +0 -1
- package/execution/__tests__/tool-view.file-changes.test.js +0 -86
- package/execution/__tests__/tool-view.file-changes.test.js.map +0 -1
- package/execution/__tests__/tool-view.fixtures.test.d.ts +0 -2
- package/execution/__tests__/tool-view.fixtures.test.d.ts.map +0 -1
- package/execution/__tests__/tool-view.fixtures.test.js +0 -152
- package/execution/__tests__/tool-view.fixtures.test.js.map +0 -1
- package/execution/__tests__/tool-view.output-ref.test.d.ts +0 -2
- package/execution/__tests__/tool-view.output-ref.test.d.ts.map +0 -1
- package/execution/__tests__/tool-view.output-ref.test.js +0 -64
- package/execution/__tests__/tool-view.output-ref.test.js.map +0 -1
- package/execution/__tests__/tool-view.read.test.d.ts +0 -2
- package/execution/__tests__/tool-view.read.test.d.ts.map +0 -1
- package/execution/__tests__/tool-view.read.test.js +0 -56
- package/execution/__tests__/tool-view.read.test.js.map +0 -1
- package/execution/__tests__/tool-view.search.test.d.ts +0 -2
- package/execution/__tests__/tool-view.search.test.d.ts.map +0 -1
- package/execution/__tests__/tool-view.search.test.js +0 -200
- package/execution/__tests__/tool-view.search.test.js.map +0 -1
- package/execution/__tests__/tool-view.shell.test.d.ts +0 -2
- package/execution/__tests__/tool-view.shell.test.d.ts.map +0 -1
- package/execution/__tests__/tool-view.shell.test.js +0 -104
- package/execution/__tests__/tool-view.shell.test.js.map +0 -1
- package/execution/__tests__/transcript.test.d.ts +0 -2
- package/execution/__tests__/transcript.test.d.ts.map +0 -1
- package/execution/__tests__/transcript.test.js +0 -591
- package/execution/__tests__/transcript.test.js.map +0 -1
- package/node.test.d.ts +0 -2
- package/node.test.d.ts.map +0 -1
- package/node.test.js +0 -35
- package/node.test.js.map +0 -1
- package/src/__tests__/billing.test.ts +0 -146
- package/src/__tests__/config.test.ts +0 -52
- package/src/__tests__/ensure-identity-account.test.ts +0 -146
- package/src/__tests__/errors.test.ts +0 -349
- package/src/__tests__/gen/errors.test.ts +0 -138
- package/src/__tests__/gen/invitation-client.test.ts +0 -132
- package/src/__tests__/gen/proto-utils.test.ts +0 -99
- package/src/__tests__/gen/session-client.test.ts +0 -208
- package/src/__tests__/guest-auth.test.ts +0 -287
- package/src/__tests__/iam-principal.test.ts +0 -82
- package/src/__tests__/manifest.test.ts +0 -362
- package/src/__tests__/mcpserver-connect.test.ts +0 -181
- package/src/__tests__/node.test.ts +0 -74
- package/src/__tests__/platform-client-auth.test.ts +0 -76
- package/src/__tests__/platform.test.ts +0 -74
- package/src/__tests__/plugin.test.ts +0 -92
- package/src/__tests__/resource-availability.test.ts +0 -118
- package/src/__tests__/runner-adapter.test.ts +0 -122
- package/src/__tests__/session.test.ts +0 -66
- package/src/__tests__/sharing.test.ts +0 -159
- package/src/__tests__/skill.test.ts +0 -150
- package/src/__tests__/stigmer.test.ts +0 -170
- package/src/__tests__/update-input-roundtrip.test.ts +0 -1007
- package/src/__tests__/update-input.test.ts +0 -250
- package/src/execution/__tests__/approval-provenance.test.ts +0 -60
- package/src/execution/__tests__/file-review-fold.corpus.test.ts +0 -127
- package/src/execution/__tests__/file-review-fold.test.ts +0 -281
- package/src/execution/__tests__/to-display-file-change.test.ts +0 -106
- package/src/execution/__tests__/tool-view.file-changes.test.ts +0 -100
- package/src/execution/__tests__/tool-view.fixtures.test.ts +0 -225
- package/src/execution/__tests__/tool-view.output-ref.test.ts +0 -76
- package/src/execution/__tests__/tool-view.read.test.ts +0 -71
- package/src/execution/__tests__/tool-view.search.test.ts +0 -264
- package/src/execution/__tests__/tool-view.shell.test.ts +0 -127
- package/src/execution/__tests__/transcript.golden.md +0 -100
- package/src/execution/__tests__/transcript.test.ts +0 -697
- package/src/node.test.ts +0 -38
|
@@ -1,362 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { clone, create, equals } from "@bufbuild/protobuf";
|
|
3
|
-
import { AgentSchema, type Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
4
|
-
import { EnvironmentSchema, type Environment } from "@stigmer/protos/ai/stigmer/agentic/environment/v1/api_pb";
|
|
5
|
-
import { ScheduleSchema, type Schedule } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
6
|
-
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
7
|
-
import { ApiResourceMetadataSchema } from "@stigmer/protos/ai/stigmer/commons/apiresource/metadata_pb";
|
|
8
|
-
import { parse as parseYaml } from "yaml";
|
|
9
|
-
import { parseManifest } from "../manifest/parse";
|
|
10
|
-
import { serializeManifest } from "../manifest/serialize";
|
|
11
|
-
import { manifestDocumentForResource } from "../manifest/document";
|
|
12
|
-
import { manifestKinds, manifestHandlerForYamlKind } from "../manifest/registry";
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Manifest engine contract tests.
|
|
16
|
-
*
|
|
17
|
-
* The engine's core promise is *round-trip fidelity against the generated
|
|
18
|
-
* proto schemas*: any resource the server returns serializes to YAML that
|
|
19
|
-
* parses back to the same proto (minus system-managed state), and any
|
|
20
|
-
* repo-authored manifest (snake_case fields, `apiVersion` spelling) parses
|
|
21
|
-
* to a proto the `apply` RPC accepts. Fixtures mirror the real manifests
|
|
22
|
-
* in the whatsapp-doctor-assistant dogfooding repo.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
// Fixtures — shaped like the whatsapp-doctor-assistant repo manifests
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
|
|
29
|
-
const AGENT_YAML = `
|
|
30
|
-
apiVersion: agentic.stigmer.ai/v1
|
|
31
|
-
kind: Agent
|
|
32
|
-
metadata:
|
|
33
|
-
name: clinic-patient-assistant
|
|
34
|
-
org: rakeshreddi098
|
|
35
|
-
spec:
|
|
36
|
-
description: Patient-facing WhatsApp assistant for the clinic.
|
|
37
|
-
instructions: |
|
|
38
|
-
You are the appointment assistant for the clinic.
|
|
39
|
-
Short messages. One question at a time.
|
|
40
|
-
`;
|
|
41
|
-
|
|
42
|
-
const ENVIRONMENT_YAML = `
|
|
43
|
-
apiVersion: agentic.stigmer.ai/v1
|
|
44
|
-
kind: Environment
|
|
45
|
-
metadata:
|
|
46
|
-
name: clinic-patient-db
|
|
47
|
-
org: rakeshreddi098
|
|
48
|
-
spec:
|
|
49
|
-
description: "Clinic records access for the patient assistant"
|
|
50
|
-
data:
|
|
51
|
-
POSTGRES_CONNECTION_URL:
|
|
52
|
-
value: "postgresql://patient_role:secret@host:5432/postgres"
|
|
53
|
-
is_secret: true
|
|
54
|
-
description: "Supabase Postgres connection URL for patient_role"
|
|
55
|
-
`;
|
|
56
|
-
|
|
57
|
-
const AGENT_CHANNEL_YAML = `
|
|
58
|
-
apiVersion: agentic.stigmer.ai/v1
|
|
59
|
-
kind: AgentChannel
|
|
60
|
-
metadata:
|
|
61
|
-
name: clinic-patient-whatsapp
|
|
62
|
-
org: rakeshreddi098
|
|
63
|
-
spec:
|
|
64
|
-
agent_ref:
|
|
65
|
-
kind: agent
|
|
66
|
-
org: rakeshreddi098
|
|
67
|
-
slug: clinic-patient-assistant
|
|
68
|
-
enabled: true
|
|
69
|
-
whatsapp:
|
|
70
|
-
phone_number_id: "1234567890"
|
|
71
|
-
app_ref:
|
|
72
|
-
kind: channel_app
|
|
73
|
-
org: rakeshreddi098
|
|
74
|
-
slug: hosipital
|
|
75
|
-
environment_refs:
|
|
76
|
-
- kind: environment
|
|
77
|
-
org: rakeshreddi098
|
|
78
|
-
slug: clinic-patient-db
|
|
79
|
-
`;
|
|
80
|
-
|
|
81
|
-
// ---------------------------------------------------------------------------
|
|
82
|
-
// parseManifest
|
|
83
|
-
// ---------------------------------------------------------------------------
|
|
84
|
-
|
|
85
|
-
describe("parseManifest", () => {
|
|
86
|
-
it("parses a snake_case Agent manifest into a full Agent proto", () => {
|
|
87
|
-
const docs = parseManifest(AGENT_YAML);
|
|
88
|
-
expect(docs).toHaveLength(1);
|
|
89
|
-
|
|
90
|
-
const doc = docs[0];
|
|
91
|
-
expect(doc.handler.yamlKind).toBe("Agent");
|
|
92
|
-
expect(doc.name).toBe("clinic-patient-assistant");
|
|
93
|
-
expect(doc.org).toBe("rakeshreddi098");
|
|
94
|
-
|
|
95
|
-
const agent = doc.message as Agent;
|
|
96
|
-
expect(agent.spec?.description).toBe(
|
|
97
|
-
"Patient-facing WhatsApp assistant for the clinic.",
|
|
98
|
-
);
|
|
99
|
-
expect(agent.spec?.instructions).toContain("appointment assistant");
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it("parses an AgentChannel manifest with enum-valued resource refs", () => {
|
|
103
|
-
const docs = parseManifest(AGENT_CHANNEL_YAML);
|
|
104
|
-
expect(docs).toHaveLength(1);
|
|
105
|
-
expect(docs[0].handler.yamlKind).toBe("AgentChannel");
|
|
106
|
-
expect(docs[0].slug).toBe("clinic-patient-whatsapp");
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it("sorts multi-document manifests into dependency apply order", () => {
|
|
110
|
-
// Authored channel-first; the Environment must still apply first.
|
|
111
|
-
const docs = parseManifest(`${AGENT_CHANNEL_YAML}\n---\n${ENVIRONMENT_YAML}`);
|
|
112
|
-
expect(docs.map((d) => d.handler.yamlKind)).toEqual([
|
|
113
|
-
"Environment",
|
|
114
|
-
"AgentChannel",
|
|
115
|
-
]);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it("injects the target org when the document omits it", () => {
|
|
119
|
-
const yaml = AGENT_YAML.replace(" org: rakeshreddi098\n", "");
|
|
120
|
-
const docs = parseManifest(yaml, { org: "acme" });
|
|
121
|
-
expect(docs[0].org).toBe("acme");
|
|
122
|
-
expect(docs[0].warning).toBeUndefined();
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it("honors the document org and warns when it differs from the target", () => {
|
|
126
|
-
const docs = parseManifest(AGENT_YAML, { org: "acme" });
|
|
127
|
-
expect(docs[0].org).toBe("rakeshreddi098");
|
|
128
|
-
expect(docs[0].warning).toContain('"rakeshreddi098"');
|
|
129
|
-
expect(docs[0].warning).toContain('"acme"');
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it("rejects unknown fields loudly (strict schema contract)", () => {
|
|
133
|
-
const yaml = AGENT_YAML.replace("spec:", "spec:\n instrctions: typo");
|
|
134
|
-
expect(() => parseManifest(yaml)).toThrow(/Invalid Agent/);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("rejects a document without a kind", () => {
|
|
138
|
-
expect(() => parseManifest("metadata:\n name: x\n")).toThrow(/'kind'/);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it("rejects unsupported kinds with the supported list", () => {
|
|
142
|
-
expect(() => parseManifest("kind: Skill\nmetadata:\n name: x\n")).toThrow(
|
|
143
|
-
/Unsupported resource kind "Skill".*Agent/s,
|
|
144
|
-
);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
it("rejects empty input with actionable guidance", () => {
|
|
148
|
-
expect(() => parseManifest(" \n")).toThrow(/empty/i);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
it("rejects malformed YAML", () => {
|
|
152
|
-
expect(() => parseManifest("kind: Agent\n bad indent: [")).toThrow(
|
|
153
|
-
/Invalid YAML/,
|
|
154
|
-
);
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// ---------------------------------------------------------------------------
|
|
159
|
-
// serializeManifest
|
|
160
|
-
// ---------------------------------------------------------------------------
|
|
161
|
-
|
|
162
|
-
describe("serializeManifest", () => {
|
|
163
|
-
const agent = create(AgentSchema, {
|
|
164
|
-
apiVersion: "agentic.stigmer.ai/v1",
|
|
165
|
-
kind: "Agent",
|
|
166
|
-
metadata: {
|
|
167
|
-
id: "agt_01example",
|
|
168
|
-
name: "clinic-patient-assistant",
|
|
169
|
-
slug: "clinic-patient-assistant",
|
|
170
|
-
org: "rakeshreddi098",
|
|
171
|
-
version: { id: "ver_01", message: "server-managed" },
|
|
172
|
-
},
|
|
173
|
-
spec: {
|
|
174
|
-
description: "Patient-facing WhatsApp assistant.",
|
|
175
|
-
instructions: "Short messages.\nOne question at a time.\n",
|
|
176
|
-
},
|
|
177
|
-
status: { defaultInstanceId: "agi_01example" },
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it("emits the canonical envelope: apiVersion spelling, no status", () => {
|
|
181
|
-
const yaml = serializeManifest(agent);
|
|
182
|
-
const doc = parseYaml(yaml) as Record<string, unknown>;
|
|
183
|
-
|
|
184
|
-
expect(Object.keys(doc)[0]).toBe("apiVersion");
|
|
185
|
-
expect(doc.apiVersion).toBe("agentic.stigmer.ai/v1");
|
|
186
|
-
expect(doc.kind).toBe("Agent");
|
|
187
|
-
expect(doc.status).toBeUndefined();
|
|
188
|
-
expect(yaml).not.toContain("api_version:");
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
it("keeps metadata.id but strips server-managed metadata.version", () => {
|
|
192
|
-
const doc = parseYaml(serializeManifest(agent)) as {
|
|
193
|
-
metadata: Record<string, unknown>;
|
|
194
|
-
};
|
|
195
|
-
expect(doc.metadata.id).toBe("agt_01example");
|
|
196
|
-
expect(doc.metadata.version).toBeUndefined();
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it("fills apiVersion and kind from the registry when the proto omits them", () => {
|
|
200
|
-
const bare = create(AgentSchema, {
|
|
201
|
-
metadata: { name: "x", org: "acme" },
|
|
202
|
-
});
|
|
203
|
-
const doc = parseYaml(serializeManifest(bare)) as Record<string, unknown>;
|
|
204
|
-
expect(doc.apiVersion).toBe("agentic.stigmer.ai/v1");
|
|
205
|
-
expect(doc.kind).toBe("Agent");
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
it("round-trips through parseManifest to an equal proto", () => {
|
|
209
|
-
const docs = parseManifest(serializeManifest(agent));
|
|
210
|
-
expect(docs).toHaveLength(1);
|
|
211
|
-
|
|
212
|
-
// The round-tripped proto matches the original minus system-managed
|
|
213
|
-
// state (status, metadata.version) — exactly what apply consumes.
|
|
214
|
-
const expected = create(AgentSchema, {
|
|
215
|
-
...agent,
|
|
216
|
-
status: undefined,
|
|
217
|
-
metadata: { ...agent.metadata!, version: undefined },
|
|
218
|
-
});
|
|
219
|
-
expect(equals(AgentSchema, docs[0].message as Agent, expected)).toBe(true);
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
it("round-trips Environment secret values byte-identically", () => {
|
|
223
|
-
const env = create(EnvironmentSchema, {
|
|
224
|
-
metadata: { name: "clinic-patient-db", org: "rakeshreddi098" },
|
|
225
|
-
spec: {
|
|
226
|
-
data: {
|
|
227
|
-
POSTGRES_CONNECTION_URL: {
|
|
228
|
-
value: "***REDACTED***",
|
|
229
|
-
isSecret: true,
|
|
230
|
-
description: "Supabase Postgres connection URL",
|
|
231
|
-
},
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
|
-
});
|
|
235
|
-
|
|
236
|
-
const docs = parseManifest(serializeManifest(env));
|
|
237
|
-
const roundTripped = docs[0].message as Environment;
|
|
238
|
-
expect(roundTripped.spec?.data.POSTGRES_CONNECTION_URL?.value).toBe(
|
|
239
|
-
"***REDACTED***",
|
|
240
|
-
);
|
|
241
|
-
expect(roundTripped.spec?.data.POSTGRES_CONNECTION_URL?.isSecret).toBe(true);
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
it("rejects messages of kinds outside the registry", () => {
|
|
245
|
-
// ApiResourceMetadata is a real proto message but not a manifest kind.
|
|
246
|
-
const notAResource = create(ApiResourceMetadataSchema, { name: "x" });
|
|
247
|
-
expect(() => serializeManifest(notAResource)).toThrow(/not.*registry/i);
|
|
248
|
-
});
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// ---------------------------------------------------------------------------
|
|
252
|
-
// manifestDocumentForResource
|
|
253
|
-
// ---------------------------------------------------------------------------
|
|
254
|
-
|
|
255
|
-
describe("manifestDocumentForResource", () => {
|
|
256
|
-
// Shaped like a server-returned schedule: full metadata (including
|
|
257
|
-
// fields the curated ScheduleInput cannot express, like tags) and a
|
|
258
|
-
// populated status — the exact input of a lossless partial edit.
|
|
259
|
-
const schedule = create(ScheduleSchema, {
|
|
260
|
-
apiVersion: "agentic.stigmer.ai/v1",
|
|
261
|
-
kind: "Schedule",
|
|
262
|
-
metadata: {
|
|
263
|
-
id: "sch_01example",
|
|
264
|
-
name: "daily-fee-reminders",
|
|
265
|
-
slug: "daily-fee-reminders",
|
|
266
|
-
org: "isc",
|
|
267
|
-
tags: ["billing"],
|
|
268
|
-
labels: { team: "ops" },
|
|
269
|
-
},
|
|
270
|
-
spec: {
|
|
271
|
-
cron: "0 9 * * *",
|
|
272
|
-
timeZone: "Asia/Kolkata",
|
|
273
|
-
enabled: true,
|
|
274
|
-
target: {
|
|
275
|
-
case: "agent",
|
|
276
|
-
value: {
|
|
277
|
-
agentRef: { kind: ApiResourceKind.agent, org: "isc", slug: "fee-reminder" },
|
|
278
|
-
message: "Send today's fee reminders.",
|
|
279
|
-
},
|
|
280
|
-
},
|
|
281
|
-
},
|
|
282
|
-
status: { consecutiveFailures: 2, pausedReason: "" },
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
it("wraps a fetched proto untouched — the lossless edit contract", () => {
|
|
286
|
-
const flipped = clone(ScheduleSchema, schedule);
|
|
287
|
-
flipped.spec!.enabled = false;
|
|
288
|
-
|
|
289
|
-
const doc = manifestDocumentForResource(flipped);
|
|
290
|
-
|
|
291
|
-
expect(doc.handler.yamlKind).toBe("Schedule");
|
|
292
|
-
expect(doc.name).toBe("daily-fee-reminders");
|
|
293
|
-
expect(doc.slug).toBe("daily-fee-reminders");
|
|
294
|
-
expect(doc.org).toBe("isc");
|
|
295
|
-
// Identity, not a copy: nothing is re-serialized or down-converted,
|
|
296
|
-
// so every field survives (the ScheduleInput path would drop tags).
|
|
297
|
-
expect(doc.message).toBe(flipped);
|
|
298
|
-
|
|
299
|
-
const expected = clone(ScheduleSchema, schedule);
|
|
300
|
-
expected.spec!.enabled = false;
|
|
301
|
-
expect(equals(ScheduleSchema, doc.message as Schedule, expected)).toBe(true);
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
it("falls back to name when the proto has no slug", () => {
|
|
305
|
-
const bare = create(AgentSchema, { metadata: { name: "x", org: "acme" } });
|
|
306
|
-
const doc = manifestDocumentForResource(bare);
|
|
307
|
-
expect(doc.slug).toBe("x");
|
|
308
|
-
});
|
|
309
|
-
|
|
310
|
-
it("rejects messages of kinds outside the registry", () => {
|
|
311
|
-
const notAResource = create(ApiResourceMetadataSchema, { name: "x" });
|
|
312
|
-
expect(() => manifestDocumentForResource(notAResource)).toThrow(
|
|
313
|
-
/not.*registry/i,
|
|
314
|
-
);
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
it("rejects a resource without metadata.name", () => {
|
|
318
|
-
const nameless = create(ScheduleSchema, { metadata: { org: "acme" } });
|
|
319
|
-
expect(() => manifestDocumentForResource(nameless)).toThrow(
|
|
320
|
-
/metadata\.name/,
|
|
321
|
-
);
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
// ---------------------------------------------------------------------------
|
|
326
|
-
// Registry invariants
|
|
327
|
-
// ---------------------------------------------------------------------------
|
|
328
|
-
|
|
329
|
-
describe("manifest registry", () => {
|
|
330
|
-
it("every handler resolves by its own YAML kind", () => {
|
|
331
|
-
for (const handler of manifestKinds()) {
|
|
332
|
-
expect(manifestHandlerForYamlKind(handler.yamlKind)).toBe(handler);
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
it("apply order is strictly increasing (no accidental ties)", () => {
|
|
337
|
-
const orders = manifestKinds().map((h) => h.applyOrder);
|
|
338
|
-
for (let i = 1; i < orders.length; i++) {
|
|
339
|
-
expect(orders[i]).toBeGreaterThan(orders[i - 1]);
|
|
340
|
-
}
|
|
341
|
-
});
|
|
342
|
-
|
|
343
|
-
it("covers the kinds the console flows depend on", () => {
|
|
344
|
-
for (const kind of ["Agent", "McpServer", "Workflow", "Environment", "AgentChannel", "ChannelApp"]) {
|
|
345
|
-
expect(manifestHandlerForYamlKind(kind), `missing handler for ${kind}`).toBeDefined();
|
|
346
|
-
}
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
it("declares the updateVisibility binding on exactly the guarded-RPC kinds (oss#573)", () => {
|
|
350
|
-
// Visibility changes go through the updateVisibility RPC only (plain
|
|
351
|
-
// updates preserve stored visibility on both editions). The binding set
|
|
352
|
-
// mirrors the kinds whose proto VisibilityConfig grants non-private
|
|
353
|
-
// levels, minus Skill (push flow, not a manifest kind) — a kind added
|
|
354
|
-
// here without the RPC fails at compile time, one dropped from here
|
|
355
|
-
// silently strands manifest-declared visibility, which this pins.
|
|
356
|
-
const withBinding = manifestKinds()
|
|
357
|
-
.filter((h) => h.updateVisibility !== undefined)
|
|
358
|
-
.map((h) => h.yamlKind)
|
|
359
|
-
.sort();
|
|
360
|
-
expect(withBinding).toEqual(["Agent", "AgentInstance", "Environment", "McpServer", "Workflow"]);
|
|
361
|
-
});
|
|
362
|
-
});
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
// Pins the shared async-connect protocol (stigmer/stigmer#425): start + poll,
|
|
2
|
-
// terminal-failure rehydration, the UNIMPLEMENTED blocking fallback, and the
|
|
3
|
-
// still-running bound. Every SDK surface (CLI, React hooks, host apps) rides
|
|
4
|
-
// this one implementation, so its contract is pinned here rather than
|
|
5
|
-
// re-tested per consumer.
|
|
6
|
-
|
|
7
|
-
import { describe, expect, it } from "vitest";
|
|
8
|
-
import { create } from "@bufbuild/protobuf";
|
|
9
|
-
import { Code, ConnectError } from "@connectrpc/connect";
|
|
10
|
-
import { McpServerSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
|
|
11
|
-
import type { McpServer } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/api_pb";
|
|
12
|
-
import { ConnectInputSchema } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/io_pb";
|
|
13
|
-
import { ConnectPhase } from "@stigmer/protos/ai/stigmer/agentic/mcpserver/v1/status_pb";
|
|
14
|
-
import { StigmerError, wrapError } from "../gen/errors.js";
|
|
15
|
-
import {
|
|
16
|
-
connectAndWait,
|
|
17
|
-
ConnectStillRunningError,
|
|
18
|
-
type McpServerConnectLane,
|
|
19
|
-
} from "../mcpserver-connect.js";
|
|
20
|
-
|
|
21
|
-
const INPUT = create(ConnectInputSchema, { mcpServerId: "mcp-1", org: "test-org" });
|
|
22
|
-
|
|
23
|
-
function server(overrides?: {
|
|
24
|
-
phase?: ConnectPhase;
|
|
25
|
-
failureCode?: string;
|
|
26
|
-
failureMessage?: string;
|
|
27
|
-
warning?: string;
|
|
28
|
-
toolName?: string;
|
|
29
|
-
}): McpServer {
|
|
30
|
-
return create(McpServerSchema, {
|
|
31
|
-
metadata: { id: "mcp-1", name: "Test Server" },
|
|
32
|
-
status: {
|
|
33
|
-
...(overrides?.toolName !== undefined
|
|
34
|
-
? { discoveredCapabilities: { tools: [{ name: overrides.toolName }] } }
|
|
35
|
-
: {}),
|
|
36
|
-
connectStatus: {
|
|
37
|
-
phase: overrides?.phase ?? ConnectPhase.connecting,
|
|
38
|
-
workflowId: "stigmer/mcp-server/connect/mcp-1",
|
|
39
|
-
failureCode: overrides?.failureCode ?? "",
|
|
40
|
-
failureMessage: overrides?.failureMessage ?? "",
|
|
41
|
-
warning: overrides?.warning ?? "",
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function unimplemented(): StigmerError {
|
|
48
|
-
return wrapError(new ConnectError("startConnect is not implemented", Code.Unimplemented));
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const NEVER = () => new Promise<McpServer>(() => {});
|
|
52
|
-
|
|
53
|
-
describe("connectAndWait", () => {
|
|
54
|
-
it("resolves with the settled resource once connect_status reports success", async () => {
|
|
55
|
-
const polled = [
|
|
56
|
-
server({ phase: ConnectPhase.connecting }),
|
|
57
|
-
server({ phase: ConnectPhase.succeeded, toolName: "search_code" }),
|
|
58
|
-
];
|
|
59
|
-
const lane: McpServerConnectLane = {
|
|
60
|
-
startConnect: async () => server(),
|
|
61
|
-
connect: NEVER,
|
|
62
|
-
get: async () => polled.shift() ?? server({ phase: ConnectPhase.succeeded }),
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const settled = await connectAndWait(lane, INPUT, { pollIntervalMs: 1 });
|
|
66
|
-
expect(settled.status?.connectStatus?.phase).toBe(ConnectPhase.succeeded);
|
|
67
|
-
expect(settled.status?.discoveredCapabilities?.tools[0]?.name).toBe("search_code");
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
it("surfaces the CONNECTING snapshot (dead-runner warning) via onStarted", async () => {
|
|
71
|
-
const lane: McpServerConnectLane = {
|
|
72
|
-
startConnect: async () => server({ warning: "no runner appears to be polling the task queue" }),
|
|
73
|
-
connect: NEVER,
|
|
74
|
-
get: async () => server({ phase: ConnectPhase.succeeded }),
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
let warning = "";
|
|
78
|
-
await connectAndWait(lane, INPUT, {
|
|
79
|
-
pollIntervalMs: 1,
|
|
80
|
-
onStarted: (started) => {
|
|
81
|
-
warning = started.status?.connectStatus?.warning ?? "";
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
expect(warning).toContain("no runner");
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("rehydrates a failed operation into the classification the blocking RPC would have thrown", async () => {
|
|
88
|
-
const lane: McpServerConnectLane = {
|
|
89
|
-
startConnect: async () => server(),
|
|
90
|
-
connect: NEVER,
|
|
91
|
-
get: async () =>
|
|
92
|
-
server({
|
|
93
|
-
phase: ConnectPhase.failed,
|
|
94
|
-
failureCode: "FailedPrecondition",
|
|
95
|
-
failureMessage: "connect failed for MCP server 'Test Server': missing credentials",
|
|
96
|
-
}),
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
const err = await connectAndWait(lane, INPUT, { pollIntervalMs: 1 }).catch((e: unknown) => e);
|
|
100
|
-
expect(err).toBeInstanceOf(StigmerError);
|
|
101
|
-
const stigmerErr = err as StigmerError;
|
|
102
|
-
// Byte-parity with the blocking lane: same code mapping, same raw message.
|
|
103
|
-
expect(stigmerErr.code).toBe("failed-precondition");
|
|
104
|
-
expect(stigmerErr.message).toBe("connect failed for MCP server 'Test Server': missing credentials");
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it("maps an unknown failure_code to the unknown classification instead of crashing", async () => {
|
|
108
|
-
const lane: McpServerConnectLane = {
|
|
109
|
-
startConnect: async () => server(),
|
|
110
|
-
connect: NEVER,
|
|
111
|
-
get: async () =>
|
|
112
|
-
server({
|
|
113
|
-
phase: ConnectPhase.failed,
|
|
114
|
-
failureCode: "SomeFutureCode",
|
|
115
|
-
failureMessage: "boom",
|
|
116
|
-
}),
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
const err = await connectAndWait(lane, INPUT, { pollIntervalMs: 1 }).catch((e: unknown) => e);
|
|
120
|
-
expect((err as StigmerError).code).toBe("unknown");
|
|
121
|
-
expect((err as StigmerError).message).toBe("boom");
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it("falls back to the blocking connect when the backend answers UNIMPLEMENTED", async () => {
|
|
125
|
-
let blockingCalled = false;
|
|
126
|
-
const lane: McpServerConnectLane = {
|
|
127
|
-
startConnect: async () => {
|
|
128
|
-
throw unimplemented();
|
|
129
|
-
},
|
|
130
|
-
connect: async () => {
|
|
131
|
-
blockingCalled = true;
|
|
132
|
-
return server({ phase: ConnectPhase.succeeded, toolName: "search_code" });
|
|
133
|
-
},
|
|
134
|
-
get: NEVER,
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
const settled = await connectAndWait(lane, INPUT);
|
|
138
|
-
expect(blockingCalled).toBe(true);
|
|
139
|
-
expect(settled.status?.discoveredCapabilities?.tools[0]?.name).toBe("search_code");
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
it("propagates non-UNIMPLEMENTED start failures untouched", async () => {
|
|
143
|
-
const startFailure = wrapError(new ConnectError("no such server", Code.NotFound));
|
|
144
|
-
const lane: McpServerConnectLane = {
|
|
145
|
-
startConnect: async () => {
|
|
146
|
-
throw startFailure;
|
|
147
|
-
},
|
|
148
|
-
connect: NEVER,
|
|
149
|
-
get: NEVER,
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
await expect(connectAndWait(lane, INPUT)).rejects.toBe(startFailure);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it("throws ConnectStillRunningError when the deadline elapses while CONNECTING", async () => {
|
|
156
|
-
const lane: McpServerConnectLane = {
|
|
157
|
-
startConnect: async () => server(),
|
|
158
|
-
connect: NEVER,
|
|
159
|
-
get: async () => server({ phase: ConnectPhase.connecting }),
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const err = await connectAndWait(lane, INPUT, { pollIntervalMs: 1, deadlineMs: 20 }).catch(
|
|
163
|
-
(e: unknown) => e,
|
|
164
|
-
);
|
|
165
|
-
expect(err).toBeInstanceOf(ConnectStillRunningError);
|
|
166
|
-
expect((err as ConnectStillRunningError).mcpServerId).toBe("mcp-1");
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it("bounds the blocking fallback with the same still-running semantics (soft, non-cancelling)", async () => {
|
|
170
|
-
const lane: McpServerConnectLane = {
|
|
171
|
-
startConnect: async () => {
|
|
172
|
-
throw unimplemented();
|
|
173
|
-
},
|
|
174
|
-
connect: NEVER,
|
|
175
|
-
get: NEVER,
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
const err = await connectAndWait(lane, INPUT, { deadlineMs: 20 }).catch((e: unknown) => e);
|
|
179
|
-
expect(err).toBeInstanceOf(ConnectStillRunningError);
|
|
180
|
-
});
|
|
181
|
-
});
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import { createNodeClient, createNodeTransport } from "../node";
|
|
3
|
-
|
|
4
|
-
describe("createNodeTransport", () => {
|
|
5
|
-
it("creates a transport with an API key", () => {
|
|
6
|
-
const transport = createNodeTransport({
|
|
7
|
-
baseUrl: "https://api.stigmer.ai",
|
|
8
|
-
apiKey: "sk_test_123",
|
|
9
|
-
});
|
|
10
|
-
expect(transport).toBeDefined();
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
it("creates a transport with a token provider", () => {
|
|
14
|
-
const transport = createNodeTransport({
|
|
15
|
-
baseUrl: "https://api.stigmer.ai",
|
|
16
|
-
getAccessToken: () => "token_abc",
|
|
17
|
-
});
|
|
18
|
-
expect(transport).toBeDefined();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("creates a transport without auth", () => {
|
|
22
|
-
const transport = createNodeTransport({
|
|
23
|
-
baseUrl: "https://api.stigmer.ai",
|
|
24
|
-
});
|
|
25
|
-
expect(transport).toBeDefined();
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("creates a native gRPC transport when protocol is grpc", () => {
|
|
29
|
-
const transport = createNodeTransport({
|
|
30
|
-
baseUrl: "https://api.stigmer.ai",
|
|
31
|
-
apiKey: "sk_test_123",
|
|
32
|
-
protocol: "grpc",
|
|
33
|
-
});
|
|
34
|
-
expect(transport).toBeDefined();
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("defaults to gRPC-web when protocol is omitted", () => {
|
|
38
|
-
const transport = createNodeTransport({
|
|
39
|
-
baseUrl: "https://api.stigmer.ai",
|
|
40
|
-
protocol: "grpc-web",
|
|
41
|
-
});
|
|
42
|
-
expect(transport).toBeDefined();
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
describe("createNodeClient", () => {
|
|
47
|
-
it("creates a Stigmer client with API key", () => {
|
|
48
|
-
const client = createNodeClient({
|
|
49
|
-
baseUrl: "https://api.stigmer.ai",
|
|
50
|
-
apiKey: "sk_test_123",
|
|
51
|
-
});
|
|
52
|
-
expect(client).toBeDefined();
|
|
53
|
-
expect(client.baseUrl).toBe("https://api.stigmer.ai");
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("creates a Stigmer client with token provider", () => {
|
|
57
|
-
const client = createNodeClient({
|
|
58
|
-
baseUrl: "https://api.stigmer.ai",
|
|
59
|
-
getAccessToken: () => "token_abc",
|
|
60
|
-
});
|
|
61
|
-
expect(client).toBeDefined();
|
|
62
|
-
expect(client.baseUrl).toBe("https://api.stigmer.ai");
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it("exposes resource sub-clients", () => {
|
|
66
|
-
const client = createNodeClient({
|
|
67
|
-
baseUrl: "https://api.stigmer.ai",
|
|
68
|
-
apiKey: "sk_test_123",
|
|
69
|
-
});
|
|
70
|
-
expect(client.agent).toBeDefined();
|
|
71
|
-
expect(client.session).toBeDefined();
|
|
72
|
-
expect(client.agentExecution).toBeDefined();
|
|
73
|
-
});
|
|
74
|
-
});
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
3
|
-
createPlatformClientAuth,
|
|
4
|
-
PlatformClientAuth,
|
|
5
|
-
} from "../platform-client-auth";
|
|
6
|
-
|
|
7
|
-
describe("createPlatformClientAuth", () => {
|
|
8
|
-
it("throws when baseUrl is missing", () => {
|
|
9
|
-
expect(() =>
|
|
10
|
-
createPlatformClientAuth({
|
|
11
|
-
baseUrl: "",
|
|
12
|
-
clientId: "stgm_cid_abc",
|
|
13
|
-
clientSecret: "stgm_cs_xyz",
|
|
14
|
-
}),
|
|
15
|
-
).toThrow("baseUrl is required");
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
it("throws when clientId is missing", () => {
|
|
19
|
-
expect(() =>
|
|
20
|
-
createPlatformClientAuth({
|
|
21
|
-
baseUrl: "https://api.stigmer.ai",
|
|
22
|
-
clientId: "",
|
|
23
|
-
clientSecret: "stgm_cs_xyz",
|
|
24
|
-
}),
|
|
25
|
-
).toThrow("clientId is required");
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it("throws when clientSecret is missing", () => {
|
|
29
|
-
expect(() =>
|
|
30
|
-
createPlatformClientAuth({
|
|
31
|
-
baseUrl: "https://api.stigmer.ai",
|
|
32
|
-
clientId: "stgm_cid_abc",
|
|
33
|
-
clientSecret: "",
|
|
34
|
-
}),
|
|
35
|
-
).toThrow("clientSecret is required");
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it("returns a PlatformClientAuth instance with valid config", () => {
|
|
39
|
-
const auth = createPlatformClientAuth({
|
|
40
|
-
baseUrl: "https://api.stigmer.ai",
|
|
41
|
-
clientId: "stgm_cid_abc",
|
|
42
|
-
clientSecret: "stgm_cs_xyz",
|
|
43
|
-
});
|
|
44
|
-
expect(auth).toBeInstanceOf(PlatformClientAuth);
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
describe("PlatformClientAuth.mintUserToken", () => {
|
|
49
|
-
it("throws StigmerError when userId is empty", async () => {
|
|
50
|
-
const auth = createPlatformClientAuth({
|
|
51
|
-
baseUrl: "https://api.stigmer.ai",
|
|
52
|
-
clientId: "stgm_cid_abc",
|
|
53
|
-
clientSecret: "stgm_cs_xyz",
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
await expect(
|
|
57
|
-
auth.mintUserToken({ userId: "" }),
|
|
58
|
-
).rejects.toThrow("userId is required");
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("throws StigmerError with invalid-argument code when userId is empty", async () => {
|
|
62
|
-
const auth = createPlatformClientAuth({
|
|
63
|
-
baseUrl: "https://api.stigmer.ai",
|
|
64
|
-
clientId: "stgm_cid_abc",
|
|
65
|
-
clientSecret: "stgm_cs_xyz",
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
try {
|
|
69
|
-
await auth.mintUserToken({ userId: "" });
|
|
70
|
-
expect.fail("should have thrown");
|
|
71
|
-
} catch (e: unknown) {
|
|
72
|
-
expect(e).toHaveProperty("code", "invalid-argument");
|
|
73
|
-
expect(e).toHaveProperty("name", "StigmerError");
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
});
|