Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,9 @@ Node.js 22's built-in `fetch()` ignores `HTTPS_PROXY`. The sandbox uses `proxy-b
| Old image served despite `:latest` push | AKS node cache | Use `imagePullPolicy: Always` or restart pods |
| "Invalid character" in base64 | `x25519:`/`ed25519:` key prefix | Apply vendored base64Decode fix |
| Node.js 22 fetch ignores HTTPS_PROXY | Built-in fetch doesn't use proxy env | Load `proxy-bootstrap.js` via `NODE_OPTIONS` |

## Implementation Quality

- **No mocks or stubs in production code.** Always provide real, working implementations. If a dependency is unavailable, build the real integration or defer the feature — never ship a mock.
- **No TODO/FIXME/HACK comments as placeholders.** If something needs to be done, do it now or track it as a GitHub issue. Code with TODO comments will not be merged.
- **No placeholder or skeleton implementations.** Every function, class, and module must be fully implemented and tested. Empty methods, `throw new Error("not implemented")`, or `// TODO` stubs are not acceptable.
43 changes: 43 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,49 @@ jobs:
- run: npm run build
- run: npm test

mesh-plugin-build:
name: Mesh Plugin Build & Test
runs-on: ubuntu-latest
defaults:
run:
working-directory: mesh-plugin
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: "22"
- run: npm install
- run: cd ../vendor/agentmesh-sdk && npm install --ignore-scripts
- run: npm run typecheck
- run: npm run build
- run: npm test

python-sidecar:
name: Python Lint & Test (AGT Sidecar)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Check for AGT sidecar code
id: check
run: |
if [ -f agt-sidecar/pyproject.toml ] || [ -f agt-sidecar/requirements.txt ]; then
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "exists=false" >> "$GITHUB_OUTPUT"
echo "::notice::AGT sidecar not yet present — skipping lint & test"
fi
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
if: steps.check.outputs.exists == 'true'
with:
python-version: "3.12"
- name: Install and test
if: steps.check.outputs.exists == 'true'
run: |
cd agt-sidecar
pip install -e ".[dev]"
python -m ruff check .
python -m pytest

bicep-validate:
name: Bicep Validation
runs-on: ubuntu-latest
Expand Down
71 changes: 71 additions & 0 deletions mesh-plugin/src/agentmesh-sdk.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Type declarations for vendored @agentmesh/sdk (no published @types package).
declare module "@agentmesh/sdk" {
export interface IdentityData {
amid: string;
signing_public_key: string;
signing_private_key: string;
exchange_public_key: string;
exchange_private_key: string;
created_at: string;
framework?: string;
framework_version?: string;
[key: string]: unknown;
}

export class Identity {
readonly amid: string;
readonly signingPublicKey: CryptoKey;
readonly signingPublicKeyRaw: Uint8Array;
readonly signingPrivateKey: CryptoKey;
readonly exchangePublicKey: CryptoKey;
readonly exchangePublicKeyRaw: Uint8Array;
readonly exchangePrivateKey: CryptoKey;
readonly createdAt: Date;

static generate(): Promise<Identity>;
static load(storage: unknown, path: string): Promise<Identity>;
static fromData(data: IdentityData): Promise<Identity>;
save(storage: unknown, path: string): Promise<void>;
toData(): Promise<IdentityData>;
get signingPublicKeyB64(): string;
}

export class MemoryStorage {
constructor();
get(key: string): Promise<string | null>;
set(key: string, value: string): Promise<void>;
delete(key: string): Promise<void>;
}

export class AgentMeshClient {
static fromIdentity(
identity: Identity,
opts?: Record<string, unknown>,
): AgentMeshClient;
connect(opts?: Record<string, unknown>): Promise<void>;
disconnect(): Promise<void>;
send(to: string, payload: unknown): Promise<string | undefined>;
onMessage(handler: (from: string, payload: unknown) => void): void;
onKnock(
handler: (
from: string,
intent: unknown,
) => Promise<{ accept: boolean }>,
): void;
addPlaintextPeer(amid: string): void;
removePlaintextPeer(amid: string): void;
getPlaintextPeers(): string[];
search(
capability: string,
opts?: Record<string, unknown>,
): Promise<unknown[]>;
get isConnected(): boolean;
get amid(): string;
}

export class RegistryClient {
constructor(opts?: Record<string, unknown>);
}

export const VERSION: string;
}
4 changes: 3 additions & 1 deletion mesh-plugin/src/connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,11 @@ export interface FileTransferAck {

// ---------------------------------------------------------------------------
// Connection class
import { IMeshTransport } from "./transport-interface.js";

// ---------------------------------------------------------------------------

export class MeshConnection {
export class MeshConnection implements IMeshTransport {
private config: ConnectionConfig;
private inbox: InboxMessage[] = [];
private maxInboxSize: number;
Expand Down
30 changes: 30 additions & 0 deletions mesh-plugin/src/transport-interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
Comment thread
imran-siddique marked this conversation as resolved.
* AGT Migration — Transport abstraction interface.
*
* Extracted from MeshConnection's public surface so the AGT adapter
* (Phase 2) can implement the same contract without changing callers.
*
* Phase 1: MeshConnection implements IMeshTransport (grounded).
* Phase 2: AgtTransport implements IMeshTransport (AGT SDK-backed).
* Phase 3: Swap implementation, remove vendor.
*/

export interface IMeshTransport {
// ── Connection lifecycle ─────────────────────────────────────
connect(): Promise<void>;
disconnect(): Promise<void>;
readonly isConnected: boolean;

// ── Messaging ────────────────────────────────────────────────
send(toAmid: string, payload: unknown): Promise<string | undefined>;

// ── Plaintext peers (Rust controller compat) ─────────────────
addPlaintextPeer(amid: string): void;
removePlaintextPeer(amid: string): void;
getPlaintextPeers(): string[];

// ── Discovery ────────────────────────────────────────────────
discover(opts?: { capability?: string; limit?: number }): Promise<
Array<{ amid: string; displayName?: string; capabilities?: string[] }>
>;
}
Loading